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:
authorJoseph Eagar <joeedh@gmail.com>2022-03-29 08:54:24 +0300
committerJoseph Eagar <joeedh@gmail.com>2022-03-29 08:54:24 +0300
commit176b331c43c5378b0a346b7c96b0934c9c5bf19f (patch)
tree546efd965d57bfa16945c2ef1ab664b2a3667471
parent2f3ace40240797100161a659a12d995e1480b91b (diff)
parent540bfbbb27966b4b8affeaa273a70beac9373b23 (diff)
Merge branch 'master' into temp-sculpt-colors
-rw-r--r--CMakeLists.txt5
-rw-r--r--build_files/build_environment/cmake/download.cmake5
-rw-r--r--build_files/cmake/Modules/FindWebP.cmake77
-rw-r--r--build_files/cmake/packaging.cmake4
-rw-r--r--build_files/cmake/platform/platform_apple.cmake9
-rw-r--r--build_files/cmake/platform/platform_unix.cmake8
-rw-r--r--build_files/cmake/platform/platform_win32.cmake10
-rw-r--r--extern/fmtlib/LICENSE.rst27
-rw-r--r--extern/fmtlib/README.blender8
-rw-r--r--extern/fmtlib/README.rst528
-rw-r--r--extern/fmtlib/include/fmt/core.h3236
-rw-r--r--extern/fmtlib/include/fmt/format-inl.h2643
-rw-r--r--extern/fmtlib/include/fmt/format.h3104
-rw-r--r--intern/cycles/blender/addon/properties.py2
-rw-r--r--intern/cycles/cmake/macros.cmake1
-rw-r--r--intern/cycles/device/hip/util.h2
-rw-r--r--intern/cycles/hydra/curves.h7
-rw-r--r--intern/cycles/hydra/mesh.h7
-rw-r--r--intern/cycles/hydra/node_util.h2
-rw-r--r--intern/cycles/hydra/pointcloud.h7
-rw-r--r--intern/cycles/hydra/volume.h7
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair_principled.h2
-rw-r--r--intern/cycles/kernel/device/cpu/image.h50
-rw-r--r--intern/cycles/kernel/film/accumulate.h12
-rw-r--r--intern/cycles/scene/integrator.cpp6
-rw-r--r--intern/cycles/util/math_float4.h10
-rw-r--r--intern/cycles/util/types_float4.h1
-rw-r--r--intern/cycles/util/types_float4_impl.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp6
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.h9
-rw-r--r--intern/ghost/intern/GHOST_XrControllerModel.cpp2
-rw-r--r--intern/itasc/WSDLSSolver.cpp2
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc28
-rw-r--r--release/license/THIRD-PARTY-LICENSES.txt2
-rw-r--r--release/scripts/modules/bl_i18n_utils/settings.py9
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils_spell_check.py2
-rw-r--r--release/scripts/modules/rna_manual_reference.py1
-rw-r--r--release/scripts/presets/keyconfig/Blender.py14
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py51
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py4
-rw-r--r--release/scripts/startup/bl_ui/space_outliner.py9
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py5
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py2
-rw-r--r--source/blender/CMakeLists.txt2
-rw-r--r--source/blender/blenfont/BLF_api.h4
-rw-r--r--source/blender/blenfont/intern/blf.c14
-rw-r--r--source/blender/blenfont/intern/blf_dir.c4
-rw-r--r--source/blender/blenfont/intern/blf_font.c18
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c4
-rw-r--r--source/blender/blenfont/intern/blf_internal.h4
-rw-r--r--source/blender/blenfont/intern/blf_internal_types.h4
-rw-r--r--source/blender/blenfont/intern/blf_thumbs.c12
-rw-r--r--source/blender/blenkernel/BKE_attribute_math.hh2
-rw-r--r--source/blender/blenkernel/BKE_curves.hh62
-rw-r--r--source/blender/blenkernel/BKE_customdata.h2
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h58
-rw-r--r--source/blender/blenkernel/BKE_image_partial_update.hh6
-rw-r--r--source/blender/blenkernel/BKE_image_save.h13
-rw-r--r--source/blender/blenkernel/BKE_layer.h32
-rw-r--r--source/blender/blenkernel/BKE_lib_id.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h6
-rw-r--r--source/blender/blenkernel/BKE_scene.h2
-rw-r--r--source/blender/blenkernel/CMakeLists.txt21
-rw-r--r--source/blender/blenkernel/intern/appdir.c12
-rw-r--r--source/blender/blenkernel/intern/blendfile_link_append.c2
-rw-r--r--source/blender/blenkernel/intern/collection.c6
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c50
-rw-r--r--source/blender/blenkernel/intern/curve.cc6
-rw-r--r--source/blender/blenkernel/intern/curve_bezier.cc50
-rw-r--r--source/blender/blenkernel/intern/curve_catmull_rom.cc6
-rw-r--r--source/blender/blenkernel/intern/curve_eval.cc4
-rw-r--r--source/blender/blenkernel/intern/curve_nurbs.cc41
-rw-r--r--source/blender/blenkernel/intern/curves.cc10
-rw-r--r--source/blender/blenkernel/intern/curves_geometry.cc176
-rw-r--r--source/blender/blenkernel/intern/curves_geometry_test.cc99
-rw-r--r--source/blender/blenkernel/intern/customdata.cc184
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/geometry_component_curves.cc4
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc67
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc467
-rw-r--r--source/blender/blenkernel/intern/image.cc328
-rw-r--r--source/blender/blenkernel/intern/image_format.cc38
-rw-r--r--source/blender/blenkernel/intern/image_partial_update.cc2
-rw-r--r--source/blender/blenkernel/intern/image_save.cc16
-rw-r--r--source/blender/blenkernel/intern/image_test.cc186
-rw-r--r--source/blender/blenkernel/intern/mesh.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc12
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc2
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c8
-rw-r--r--source/blender/blenkernel/intern/mesh_normals.cc46
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc3
-rw-r--r--source/blender/blenkernel/intern/object.cc6
-rw-r--r--source/blender/blenkernel/intern/packedFile.c16
-rw-r--r--source/blender/blenkernel/intern/particle.c8
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c6
-rw-r--r--source/blender/blenkernel/intern/particle_system.c14
-rw-r--r--source/blender/blenkernel/intern/scene.cc (renamed from source/blender/blenkernel/intern/scene.c)515
-rw-r--r--source/blender/blenkernel/intern/studiolight.c14
-rw-r--r--source/blender/blenkernel/intern/subdiv.c2
-rw-r--r--source/blender/blenlib/BLI_enumerable_thread_specific.hh19
-rw-r--r--source/blender/blenlib/BLI_math_base.hh22
-rw-r--r--source/blender/blenlib/BLI_math_statistics.h8
-rw-r--r--source/blender/blenlib/BLI_math_vec_types.hh11
-rw-r--r--source/blender/blenlib/BLI_math_vector.h7
-rw-r--r--source/blender/blenlib/BLI_math_vector.hh6
-rw-r--r--source/blender/blenlib/BLI_timeit.hh35
-rw-r--r--source/blender/blenlib/CMakeLists.txt6
-rw-r--r--source/blender/blenlib/intern/BLI_filelist.c16
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.cc22
-rw-r--r--source/blender/blenlib/intern/fileops.c6
-rw-r--r--source/blender/blenlib/intern/generic_virtual_array.cc5
-rw-r--r--source/blender/blenlib/intern/math_statistics.c24
-rw-r--r--source/blender/blenlib/intern/math_vector.c13
-rw-r--r--source/blender/blenlib/intern/timeit.cc18
-rw-r--r--source/blender/blenlib/tests/BLI_math_base_test.cc5
-rw-r--r--source/blender/blenlib/tests/BLI_math_vector_test.cc20
-rw-r--r--source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc62
-rw-r--r--source/blender/blenlib/tests/performance/BLI_task_performance_test.cc6
-rw-r--r--source/blender/blenloader/intern/versioning_300.c35
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_convert.cc4
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_normals.c16
-rw-r--r--source/blender/compositor/intern/COM_Debug.cc6
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc4
-rw-r--r--source/blender/draw/CMakeLists.txt5
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows_cascade.c22
-rw-r--r--source/blender/draw/engines/image/image_drawing_mode.hh21
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curves.cc6
-rw-r--r--source/blender/draw/intern/draw_common.c7
-rw-r--r--source/blender/draw/intern/draw_common.h122
-rw-r--r--source/blender/draw/intern/draw_common_shader_shared.h245
-rw-r--r--source/blender/draw/intern/draw_shader_shared.h2
-rw-r--r--source/blender/draw/intern/draw_view_data.cc3
-rw-r--r--source/blender/draw/intern/shaders/draw_view_info.hh10
-rw-r--r--source/blender/editors/animation/keyframes_edit.c4
-rw-r--r--source/blender/editors/armature/meshlaplacian.c157
-rw-r--r--source/blender/editors/asset/intern/asset_indexer.cc7
-rw-r--r--source/blender/editors/curve/editcurve.c4
-rw-r--r--source/blender/editors/curve/editfont.c22
-rw-r--r--source/blender/editors/curves/intern/curves_add.cc4
-rw-r--r--source/blender/editors/gpencil/CMakeLists.txt4
-rw-r--r--source/blender/editors/gpencil/gpencil_bake_animation.cc (renamed from source/blender/editors/gpencil/gpencil_bake_animation.c)57
-rw-r--r--source/blender/editors/gpencil/gpencil_convert.c56
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c31
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c27
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h8
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c30
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.cc (renamed from source/blender/editors/gpencil/gpencil_mesh.c)71
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c26
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c8
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h16
-rw-r--r--source/blender/editors/include/ED_view3d.h5
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c12
-rw-r--r--source/blender/editors/interface/interface_draw.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c3
-rw-r--r--source/blender/editors/io/io_usd.c4
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/object/object_bake_api.c106
-rw-r--r--source/blender/editors/object/object_gpencil_modifier.c2
-rw-r--r--source/blender/editors/object/object_hook.c102
-rw-r--r--source/blender/editors/object/object_modifier.c56
-rw-r--r--source/blender/editors/object/object_transform.cc4
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c14
-rw-r--r--source/blender/editors/physics/rigidbody_world.c2
-rw-r--r--source/blender/editors/render/render_preview.cc16
-rw-r--r--source/blender/editors/scene/CMakeLists.txt2
-rw-r--r--source/blender/editors/screen/area.c1
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt4
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc4
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_add.cc16
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_comb.cc10
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_delete.cc2
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_ops.cc12
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_boundary.c9
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_smooth.c2
-rw-r--r--source/blender/editors/space_action/action_edit.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c8
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c28
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt3
-rw-r--r--source/blender/editors/space_file/filelist.c154
-rw-r--r--source/blender/editors/space_file/fsmenu.c12
-rw-r--r--source/blender/editors/space_image/CMakeLists.txt3
-rw-r--r--source/blender/editors/space_image/image_ops.c9
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.cc2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.cc1
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.cc11
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc35
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.cc1
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display.hh3
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_libraries.cc2
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_override_library.cc145
-rw-r--r--source/blender/editors/space_outliner/tree/tree_display_view_layer.cc9
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.cc1
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element.hh3
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_id.cc11
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_id.hh1
-rw-r--r--source/blender/editors/space_outliner/tree/tree_element_rna.cc2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c39
-rw-r--r--source/blender/editors/space_text/text_ops.c22
-rw-r--r--source/blender/editors/space_view3d/view3d_cursor_snap.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c263
-rw-r--r--source/blender/editors/transform/CMakeLists.txt2
-rw-r--r--source/blender/editors/transform/transform.c39
-rw-r--r--source/blender/editors/transform/transform.h5
-rw-r--r--source/blender/editors/transform/transform_constraints.c15
-rw-r--r--source/blender/editors/transform/transform_convert_object_texspace.c2
-rw-r--r--source/blender/editors/transform/transform_generics.c3
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c4
-rw-r--r--source/blender/editors/transform/transform_snap.c108
-rw-r--r--source/blender/editors/transform/transform_snap_object.cc (renamed from source/blender/editors/transform/transform_snap_object.c)462
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.cpp8
-rw-r--r--source/blender/freestyle/intern/python/BPy_MediumType.cpp2
-rw-r--r--source/blender/functions/intern/field.cc36
-rw-r--r--source/blender/geometry/intern/realize_instances.cc8
-rw-r--r--source/blender/gpencil_modifiers/CMakeLists.txt1
-rw-r--r--source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c1
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencildash.c36
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c628
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c10
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c77
-rw-r--r--source/blender/gpu/CMakeLists.txt41
-rw-r--r--source/blender/gpu/intern/gpu_shader_create_info.cc16
-rw-r--r--source/blender/gpu/opengl/gl_shader.cc2
-rw-r--r--source/blender/gpu/opengl/gl_shader_log.cc3
-rw-r--r--source/blender/imbuf/CMakeLists.txt13
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h3
-rw-r--r--source/blender/imbuf/IMB_openexr.h6
-rw-r--r--source/blender/imbuf/intern/IMB_filetype.h13
-rw-r--r--source/blender/imbuf/intern/colormanagement.c25
-rw-r--r--source/blender/imbuf/intern/filetype.c14
-rw-r--r--source/blender/imbuf/intern/openexr/CMakeLists.txt2
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp34
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_stub.cpp6
-rw-r--r--source/blender/imbuf/intern/util.c13
-rw-r--r--source/blender/imbuf/intern/webp.c129
-rw-r--r--source/blender/io/gpencil/gpencil_io.h4
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.cc6
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_base.hh6
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_capi.cc12
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc16
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_svg.cc16
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_export_svg.hh2
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_svg.cc6
-rw-r--r--source/blender/io/gpencil/intern/gpencil_io_import_svg.hh2
-rw-r--r--source/blender/io/usd/CMakeLists.txt8
-rw-r--r--source/blender/io/usd/intern/usd_capi_import.cc2
-rw-r--r--source/blender/io/usd/intern/usd_reader_light.cc21
-rw-r--r--source/blender/io/usd/intern/usd_reader_stage.cc17
-rw-r--r--source/blender/io/usd/intern/usd_reader_volume.cc12
-rw-r--r--source/blender/io/usd/intern/usd_reader_xform.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_light.cc48
-rw-r--r--source/blender/io/usd/intern/usd_writer_material.cc12
-rw-r--r--source/blender/io/wavefront_obj/CMakeLists.txt1
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_io.hh144
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc4
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc2
-rw-r--r--source/blender/makesdna/DNA_curves_types.h1
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h2
-rw-r--r--source/blender/makesdna/DNA_defs.h97
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_defaults.h11
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h52
-rw-r--r--source/blender/makesdna/DNA_modifier_defaults.h20
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h22
-rw-r--r--source/blender/makesdna/DNA_node_types.h2
-rw-r--r--source/blender/makesdna/DNA_object_types.h4
-rw-r--r--source/blender/makesdna/DNA_particle_defaults.h4
-rw-r--r--source/blender/makesdna/DNA_particle_types.h2
-rw-r--r--source/blender/makesdna/DNA_pointcache_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/makesdna/DNA_screen_types.h2
-rw-r--r--source/blender/makesdna/DNA_space_types.h13
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h3
-rw-r--r--source/blender/makesdna/intern/CMakeLists.txt2
-rw-r--r--source/blender/makesdna/intern/dna_defaults.c2
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h21
-rw-r--r--source/blender/makesdna/intern/dna_utils.c18
-rw-r--r--source/blender/makesdna/intern/makesdna.c12
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt4
-rw-r--r--source/blender/makesrna/intern/rna_ID.c6
-rw-r--r--source/blender/makesrna/intern/rna_brush.c5
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c166
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c28
-rw-r--r--source/blender/makesrna/intern/rna_particle.c8
-rw-r--r--source/blender/makesrna/intern/rna_scene.c12
-rw-r--r--source/blender/makesrna/intern/rna_shader_fx.c1
-rw-r--r--source/blender/makesrna/intern/rna_space.c7
-rw-r--r--source/blender/makesrna/intern/rna_text.c8
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c10
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c21
-rw-r--r--source/blender/modifiers/intern/MOD_array.c34
-rw-r--r--source/blender/modifiers/intern/MOD_build.c52
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c35
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c6
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c10
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c111
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c14
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c25
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c53
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c47
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c167
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c143
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c12
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc167
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c39
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c18
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c8
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c102
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.cc2
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c4
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c122
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c26
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c9
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c22
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c13
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c19
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c147
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c48
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c4
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c249
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c196
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c4
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c20
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c204
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c6
-rw-r--r--source/blender/modifiers/intern/MOD_util.c16
-rw-r--r--source/blender/modifiers/intern/MOD_util.h2
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c36
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c12
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c18
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c24
-rw-r--r--source/blender/modifiers/intern/MOD_weighted_normal.c162
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c22
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c97
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c81
-rw-r--r--source/blender/nodes/composite/CMakeLists.txt2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc8
-rw-r--r--source/blender/nodes/geometry/CMakeLists.txt2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc26
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc8
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc4
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc300
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc159
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc6
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_transform.cc4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.cc2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c2
-rw-r--r--source/blender/python/generic/blf_py_api.c24
-rw-r--r--source/blender/python/gpu/gpu_py_shader.c4
-rw-r--r--source/blender/python/gpu/gpu_py_state.c2
-rw-r--r--source/blender/python/intern/CMakeLists.txt4
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c10
-rw-r--r--source/blender/python/intern/bpy_interface_run.c73
-rw-r--r--source/blender/python/intern/bpy_rna_array.c8
-rw-r--r--source/blender/python/intern/bpy_traceback.c109
-rw-r--r--source/blender/python/intern/bpy_traceback.h3
-rw-r--r--source/blender/python/mathutils/mathutils.c122
-rw-r--r--source/blender/python/mathutils/mathutils.h4
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c396
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.h24
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c428
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.h11
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c39
-rw-r--r--source/blender/python/mathutils/mathutils_noise.c25
-rw-r--r--source/blender/render/RE_bake.h20
-rw-r--r--source/blender/render/RE_engine.h4
-rw-r--r--source/blender/render/intern/bake.c36
-rw-r--r--source/blender/render/intern/engine.c6
-rw-r--r--source/blender/render/intern/multires_bake.c12
-rw-r--r--source/blender/render/intern/pipeline.c18
-rw-r--r--source/blender/render/intern/render_result.c2
-rw-r--r--source/blender/render/intern/texture_margin.cc4
-rw-r--r--source/blender/sequencer/SEQ_animation.h12
-rw-r--r--source/blender/sequencer/intern/animation.c29
-rw-r--r--source/blender/sequencer/intern/disk_cache.c7
-rw-r--r--source/blender/sequencer/intern/effects.c4
-rw-r--r--source/blender/sequencer/intern/strip_edit.c11
-rw-r--r--source/blender/windowmanager/WM_api.h33
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c18
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c10
-rw-r--r--source/blender/windowmanager/intern/wm_operator_props.c12
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c2
-rw-r--r--source/creator/creator_args.c38
397 files changed, 17302 insertions, 5262 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bf40347e2ef..ca457ab6b37 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -284,6 +284,7 @@ option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON)
option(WITH_IMAGE_DDS "Enable DDS Image Support" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_HDR "Enable HDR Image Support" ON)
+option(WITH_IMAGE_WEBP "Enable WebP Image Support" OFF)
# Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
@@ -445,7 +446,7 @@ if(NOT APPLE)
endif()
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
- set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
+ set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for")
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
endif()
@@ -1973,7 +1974,7 @@ if(FIRST_RUN)
set(_msg " - ${_setting}")
string(LENGTH "${_msg}" _len)
- while("32" GREATER "${_len}")
+ while("36" GREATER "${_len}")
string(APPEND _msg " ")
math(EXPR _len "${_len} + 1")
endwhile()
diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake
index b92073636f5..5ca46c15d8d 100644
--- a/build_files/build_environment/cmake/download.cmake
+++ b/build_files/build_environment/cmake/download.cmake
@@ -1,11 +1,16 @@
# SPDX-License-Identifier: GPL-2.0-or-later
+## Update and uncomment this in the release branch
+# set(BLENDER_VERSION 3.1)
+
function(download_source dep)
set(TARGET_FILE ${${dep}_FILE})
set(TARGET_HASH_TYPE ${${dep}_HASH_TYPE})
set(TARGET_HASH ${${dep}_HASH})
if(PACKAGE_USE_UPSTREAM_SOURCES)
set(TARGET_URI ${${dep}_URI})
+ elseif(BLENDER_VERSION)
+ set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/tags/blender-${BLENDER_VERSION}-release/lib/packages/${TARGET_FILE})
else()
set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/trunk/lib/packages/${TARGET_FILE})
endif()
diff --git a/build_files/cmake/Modules/FindWebP.cmake b/build_files/cmake/Modules/FindWebP.cmake
new file mode 100644
index 00000000000..741c48ec447
--- /dev/null
+++ b/build_files/cmake/Modules/FindWebP.cmake
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright 2022 Blender Foundation.
+
+# - Find WebP library
+# Find the native WebP includes and library
+# This module defines
+# WEBP_INCLUDE_DIRS, where to find WebP headers, Set when WebP is found.
+# WEBP_LIBRARIES, libraries to link against to use WebP.
+# WEBP_ROOT_DIR, The base directory to search for WebP.
+# This can also be an environment variable.
+# WEBP_FOUND, If false, do not try to use WebP.
+#
+# also defined, but not for general use are
+# WEBP_LIBRARY, where to find the WEBP library.
+
+# If WEBP_ROOT_DIR was defined in the environment, use it.
+IF(NOT WEBP_ROOT_DIR AND NOT $ENV{WEBP_ROOT_DIR} STREQUAL "")
+ SET(WEBP_ROOT_DIR $ENV{WEBP_ROOT_DIR})
+ENDIF()
+
+SET(_webp_SEARCH_DIRS
+ ${WEBP_ROOT_DIR}
+ /opt/lib/webp
+)
+
+FIND_PATH(WEBP_INCLUDE_DIR
+ NAMES
+ webp/types.h
+ HINTS
+ ${_webp_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+SET(_webp_FIND_COMPONENTS
+ webp
+ webpmux
+ webpdemux
+)
+
+SET(_webp_LIBRARIES)
+FOREACH(COMPONENT ${_webp_FIND_COMPONENTS})
+ STRING(TOUPPER ${COMPONENT} UPPERCOMPONENT)
+
+ FIND_LIBRARY(WEBP_${UPPERCOMPONENT}_LIBRARY
+ NAMES
+ ${COMPONENT}
+ NAMES_PER_DIR
+ HINTS
+ ${_webp_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib lib/static
+ )
+ LIST(APPEND _webp_LIBRARIES "${WEBP_${UPPERCOMPONENT}_LIBRARY}")
+ENDFOREACH()
+
+IF(${WEBP_WEBP_LIBRARY_NOTFOUND})
+ set(WEBP_FOUND FALSE)
+ELSE()
+ # handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if
+ # all listed variables are TRUE
+ INCLUDE(FindPackageHandleStandardArgs)
+ FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG _webp_LIBRARIES WEBP_INCLUDE_DIR)
+
+ IF(WEBP_FOUND)
+ get_filename_component(WEBP_LIBRARY_DIR ${WEBP_WEBP_LIBRARY} DIRECTORY)
+ SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR})
+ SET(WEBP_LIBRARIES ${_webp_LIBRARIES})
+ ELSE()
+ SET(WEBPL_PUGIXML_FOUND FALSE)
+ ENDIF()
+ENDIF()
+
+MARK_AS_ADVANCED(
+ WEBP_INCLUDE_DIR
+ WEBP_LIBRARY_DIR
+)
diff --git a/build_files/cmake/packaging.cmake b/build_files/cmake/packaging.cmake
index 2079cb7df51..f6073eba82e 100644
--- a/build_files/cmake/packaging.cmake
+++ b/build_files/cmake/packaging.cmake
@@ -106,8 +106,8 @@ if(WIN32)
set(CPACK_WIX_LIGHT_EXTRA_FLAGS -dcl:medium)
endif()
-set(CPACK_PACKAGE_EXECUTABLES "blender-launcher" "blender")
-set(CPACK_CREATE_DESKTOP_LINKS "blender-launcher" "blender")
+set(CPACK_PACKAGE_EXECUTABLES "blender-launcher" "Blender")
+set(CPACK_CREATE_DESKTOP_LINKS "blender-launcher" "Blender")
include(CPack)
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index b09f2f8917b..43ce23081af 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -232,6 +232,15 @@ if(WITH_IMAGE_TIFF)
endif()
endif()
+if(WITH_IMAGE_WEBP)
+ set(WEBP_ROOT_DIR ${LIBDIR}/webp)
+ find_package(WebP)
+ if(NOT WEBP_FOUND)
+ message(WARNING "WebP not found, disabling WITH_IMAGE_WEBP")
+ set(WITH_IMAGE_WEBP OFF)
+ endif()
+endif()
+
if(WITH_BOOST)
set(Boost_NO_BOOST_CMAKE ON)
set(BOOST_ROOT ${LIBDIR}/boost)
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index 0a7119802c8..cc168476d5d 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -368,6 +368,14 @@ if(WITH_PUGIXML)
endif()
endif()
+if(WITH_IMAGE_WEBP)
+ set(WEBP_ROOT_DIR ${LIBDIR}/webp)
+ find_package_wrapper(WebP)
+ if(NOT WEBP_FOUND)
+ set(WITH_IMAGE_WEBP OFF)
+ endif()
+endif()
+
if(WITH_OPENIMAGEIO)
find_package_wrapper(OpenImageIO)
set(OPENIMAGEIO_LIBRARIES
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index ca4af2274e6..8ae38e03fb1 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -343,6 +343,16 @@ if(WITH_FFTW3)
set(FFTW3_LIBPATH ${FFTW3}/lib)
endif()
+windows_find_package(WebP)
+if(NOT WEBP_FOUND)
+ if(EXISTS ${LIBDIR}/webp)
+ set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include)
+ set(WEBP_ROOT_DIR ${LIBDIR}/webp)
+ set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib)
+ set(WEBP_FOUND ON)
+ endif()
+endif()
+
if(WITH_OPENCOLLADA)
set(OPENCOLLADA ${LIBDIR}/opencollada)
diff --git a/extern/fmtlib/LICENSE.rst b/extern/fmtlib/LICENSE.rst
new file mode 100644
index 00000000000..f0ec3db4d2a
--- /dev/null
+++ b/extern/fmtlib/LICENSE.rst
@@ -0,0 +1,27 @@
+Copyright (c) 2012 - present, Victor Zverovich
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+--- Optional exception to the license ---
+
+As an exception, if, as a result of your compiling your source code, portions
+of this Software are embedded into a machine-executable object form of such
+source code, you may redistribute such embedded portions in such object form
+without including the above copyright and permission notices.
diff --git a/extern/fmtlib/README.blender b/extern/fmtlib/README.blender
new file mode 100644
index 00000000000..98c5684305e
--- /dev/null
+++ b/extern/fmtlib/README.blender
@@ -0,0 +1,8 @@
+Project: {fmt}
+URL: https://github.com/fmtlib/fmt
+License: MIT
+Upstream version: 8.1.1 (b6f4cea)
+Local modifications:
+
+- Took only files needed for Blender: LICENSE, README and include/fmt
+ folder's core.h, format-inl.h, format.h
diff --git a/extern/fmtlib/README.rst b/extern/fmtlib/README.rst
new file mode 100644
index 00000000000..394f28d97bb
--- /dev/null
+++ b/extern/fmtlib/README.rst
@@ -0,0 +1,528 @@
+{fmt}
+=====
+
+.. image:: https://github.com/fmtlib/fmt/workflows/linux/badge.svg
+ :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Alinux
+
+.. image:: https://github.com/fmtlib/fmt/workflows/macos/badge.svg
+ :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Amacos
+
+.. image:: https://github.com/fmtlib/fmt/workflows/windows/badge.svg
+ :target: https://github.com/fmtlib/fmt/actions?query=workflow%3Awindows
+
+.. image:: https://ci.appveyor.com/api/projects/status/ehjkiefde6gucy1v?svg=true
+ :target: https://ci.appveyor.com/project/vitaut/fmt
+
+.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/fmt.svg
+ :alt: fmt is continuously fuzzed at oss-fuzz
+ :target: https://bugs.chromium.org/p/oss-fuzz/issues/list?\
+ colspec=ID%20Type%20Component%20Status%20Proj%20Reported%20Owner%20\
+ Summary&q=proj%3Dfmt&can=1
+
+.. image:: https://img.shields.io/badge/stackoverflow-fmt-blue.svg
+ :alt: Ask questions at StackOverflow with the tag fmt
+ :target: https://stackoverflow.com/questions/tagged/fmt
+
+**{fmt}** is an open-source formatting library providing a fast and safe
+alternative to C stdio and C++ iostreams.
+
+If you like this project, please consider donating to the BYSOL
+Foundation that helps victims of political repressions in Belarus:
+https://bysol.org/en/bs/general/.
+
+`Documentation <https://fmt.dev>`__
+
+Q&A: ask questions on `StackOverflow with the tag fmt
+<https://stackoverflow.com/questions/tagged/fmt>`_.
+
+Try {fmt} in `Compiler Explorer <https://godbolt.org/z/Eq5763>`_.
+
+Features
+--------
+
+* Simple `format API <https://fmt.dev/latest/api.html>`_ with positional arguments
+ for localization
+* Implementation of `C++20 std::format
+ <https://en.cppreference.com/w/cpp/utility/format>`__
+* `Format string syntax <https://fmt.dev/latest/syntax.html>`_ similar to Python's
+ `format <https://docs.python.org/3/library/stdtypes.html#str.format>`_
+* Fast IEEE 754 floating-point formatter with correct rounding, shortness and
+ round-trip guarantees
+* Safe `printf implementation
+ <https://fmt.dev/latest/api.html#printf-formatting>`_ including the POSIX
+ extension for positional arguments
+* Extensibility: `support for user-defined types
+ <https://fmt.dev/latest/api.html#formatting-user-defined-types>`_
+* High performance: faster than common standard library implementations of
+ ``(s)printf``, iostreams, ``to_string`` and ``to_chars``, see `Speed tests`_
+ and `Converting a hundred million integers to strings per second
+ <http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_
+* Small code size both in terms of source code with the minimum configuration
+ consisting of just three files, ``core.h``, ``format.h`` and ``format-inl.h``,
+ and compiled code; see `Compile time and code bloat`_
+* Reliability: the library has an extensive set of `tests
+ <https://github.com/fmtlib/fmt/tree/master/test>`_ and is `continuously fuzzed
+ <https://bugs.chromium.org/p/oss-fuzz/issues/list?colspec=ID%20Type%20
+ Component%20Status%20Proj%20Reported%20Owner%20Summary&q=proj%3Dfmt&can=1>`_
+* Safety: the library is fully type safe, errors in format strings can be
+ reported at compile time, automatic memory management prevents buffer overflow
+ errors
+* Ease of use: small self-contained code base, no external dependencies,
+ permissive MIT `license
+ <https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_
+* `Portability <https://fmt.dev/latest/index.html#portability>`_ with
+ consistent output across platforms and support for older compilers
+* Clean warning-free codebase even on high warning levels such as
+ ``-Wall -Wextra -pedantic``
+* Locale-independence by default
+* Optional header-only configuration enabled with the ``FMT_HEADER_ONLY`` macro
+
+See the `documentation <https://fmt.dev>`_ for more details.
+
+Examples
+--------
+
+**Print to stdout** (`run <https://godbolt.org/z/Tevcjh>`_)
+
+.. code:: c++
+
+ #include <fmt/core.h>
+
+ int main() {
+ fmt::print("Hello, world!\n");
+ }
+
+**Format a string** (`run <https://godbolt.org/z/oK8h33>`_)
+
+.. code:: c++
+
+ std::string s = fmt::format("The answer is {}.", 42);
+ // s == "The answer is 42."
+
+**Format a string using positional arguments** (`run <https://godbolt.org/z/Yn7Txe>`_)
+
+.. code:: c++
+
+ std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
+ // s == "I'd rather be happy than right."
+
+**Print chrono durations** (`run <https://godbolt.org/z/K8s4Mc>`_)
+
+.. code:: c++
+
+ #include <fmt/chrono.h>
+
+ int main() {
+ using namespace std::literals::chrono_literals;
+ fmt::print("Default format: {} {}\n", 42s, 100ms);
+ fmt::print("strftime-like format: {:%H:%M:%S}\n", 3h + 15min + 30s);
+ }
+
+Output::
+
+ Default format: 42s 100ms
+ strftime-like format: 03:15:30
+
+**Print a container** (`run <https://godbolt.org/z/MjsY7c>`_)
+
+.. code:: c++
+
+ #include <vector>
+ #include <fmt/ranges.h>
+
+ int main() {
+ std::vector<int> v = {1, 2, 3};
+ fmt::print("{}\n", v);
+ }
+
+Output::
+
+ [1, 2, 3]
+
+**Check a format string at compile time**
+
+.. code:: c++
+
+ std::string s = fmt::format("{:d}", "I am not a number");
+
+This gives a compile-time error in C++20 because ``d`` is an invalid format
+specifier for a string.
+
+**Write a file from a single thread**
+
+.. code:: c++
+
+ #include <fmt/os.h>
+
+ int main() {
+ auto out = fmt::output_file("guide.txt");
+ out.print("Don't {}", "Panic");
+ }
+
+This can be `5 to 9 times faster than fprintf
+<http://www.zverovich.net/2020/08/04/optimal-file-buffer-size.html>`_.
+
+**Print with colors and text styles**
+
+.. code:: c++
+
+ #include <fmt/color.h>
+
+ int main() {
+ fmt::print(fg(fmt::color::crimson) | fmt::emphasis::bold,
+ "Hello, {}!\n", "world");
+ fmt::print(fg(fmt::color::floral_white) | bg(fmt::color::slate_gray) |
+ fmt::emphasis::underline, "Hello, {}!\n", "мир");
+ fmt::print(fg(fmt::color::steel_blue) | fmt::emphasis::italic,
+ "Hello, {}!\n", "世界");
+ }
+
+Output on a modern terminal:
+
+.. image:: https://user-images.githubusercontent.com/
+ 576385/88485597-d312f600-cf2b-11ea-9cbe-61f535a86e28.png
+
+Benchmarks
+----------
+
+Speed tests
+~~~~~~~~~~~
+
+================= ============= ===========
+Library Method Run Time, s
+================= ============= ===========
+libc printf 1.04
+libc++ std::ostream 3.05
+{fmt} 6.1.1 fmt::print 0.75
+Boost Format 1.67 boost::format 7.24
+Folly Format folly::format 2.23
+================= ============= ===========
+
+{fmt} is the fastest of the benchmarked methods, ~35% faster than ``printf``.
+
+The above results were generated by building ``tinyformat_test.cpp`` on macOS
+10.14.6 with ``clang++ -O3 -DNDEBUG -DSPEED_TEST -DHAVE_FORMAT``, and taking the
+best of three runs. In the test, the format string ``"%0.10f:%04d:%+g:%s:%p:%c:%%\n"``
+or equivalent is filled 2,000,000 times with output sent to ``/dev/null``; for
+further details refer to the `source
+<https://github.com/fmtlib/format-benchmark/blob/master/src/tinyformat-test.cc>`_.
+
+{fmt} is up to 20-30x faster than ``std::ostringstream`` and ``sprintf`` on
+floating-point formatting (`dtoa-benchmark <https://github.com/fmtlib/dtoa-benchmark>`_)
+and faster than `double-conversion <https://github.com/google/double-conversion>`_ and
+`ryu <https://github.com/ulfjack/ryu>`_:
+
+.. image:: https://user-images.githubusercontent.com/576385/
+ 95684665-11719600-0ba8-11eb-8e5b-972ff4e49428.png
+ :target: https://fmt.dev/unknown_mac64_clang12.0.html
+
+Compile time and code bloat
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The script `bloat-test.py
+<https://github.com/fmtlib/format-benchmark/blob/master/bloat-test.py>`_
+from `format-benchmark <https://github.com/fmtlib/format-benchmark>`_
+tests compile time and code bloat for nontrivial projects.
+It generates 100 translation units and uses ``printf()`` or its alternative
+five times in each to simulate a medium sized project. The resulting
+executable size and compile time (Apple LLVM version 8.1.0 (clang-802.0.42),
+macOS Sierra, best of three) is shown in the following tables.
+
+**Optimized build (-O3)**
+
+============= =============== ==================== ==================
+Method Compile Time, s Executable size, KiB Stripped size, KiB
+============= =============== ==================== ==================
+printf 2.6 29 26
+printf+string 16.4 29 26
+iostreams 31.1 59 55
+{fmt} 19.0 37 34
+Boost Format 91.9 226 203
+Folly Format 115.7 101 88
+============= =============== ==================== ==================
+
+As you can see, {fmt} has 60% less overhead in terms of resulting binary code
+size compared to iostreams and comes pretty close to ``printf``. Boost Format
+and Folly Format have the largest overheads.
+
+``printf+string`` is the same as ``printf`` but with extra ``<string>``
+include to measure the overhead of the latter.
+
+**Non-optimized build**
+
+============= =============== ==================== ==================
+Method Compile Time, s Executable size, KiB Stripped size, KiB
+============= =============== ==================== ==================
+printf 2.2 33 30
+printf+string 16.0 33 30
+iostreams 28.3 56 52
+{fmt} 18.2 59 50
+Boost Format 54.1 365 303
+Folly Format 79.9 445 430
+============= =============== ==================== ==================
+
+``libc``, ``lib(std)c++`` and ``libfmt`` are all linked as shared libraries to
+compare formatting function overhead only. Boost Format is a
+header-only library so it doesn't provide any linkage options.
+
+Running the tests
+~~~~~~~~~~~~~~~~~
+
+Please refer to `Building the library`__ for the instructions on how to build
+the library and run the unit tests.
+
+__ https://fmt.dev/latest/usage.html#building-the-library
+
+Benchmarks reside in a separate repository,
+`format-benchmarks <https://github.com/fmtlib/format-benchmark>`_,
+so to run the benchmarks you first need to clone this repository and
+generate Makefiles with CMake::
+
+ $ git clone --recursive https://github.com/fmtlib/format-benchmark.git
+ $ cd format-benchmark
+ $ cmake .
+
+Then you can run the speed test::
+
+ $ make speed-test
+
+or the bloat test::
+
+ $ make bloat-test
+
+Migrating code
+--------------
+
+`clang-tidy-fmt <https://github.com/mikecrowe/clang-tidy-fmt>`_ provides clang
+tidy checks for converting occurrences of ``printf`` and ``fprintf`` to
+``fmt::print``.
+
+Projects using this library
+---------------------------
+
+* `0 A.D. <https://play0ad.com/>`_: a free, open-source, cross-platform
+ real-time strategy game
+
+* `2GIS <https://2gis.ru/>`_: free business listings with a city map
+
+* `AMPL/MP <https://github.com/ampl/mp>`_:
+ an open-source library for mathematical programming
+
+* `Aseprite <https://github.com/aseprite/aseprite>`_:
+ animated sprite editor & pixel art tool
+
+* `AvioBook <https://www.aviobook.aero/en>`_: a comprehensive aircraft
+ operations suite
+
+* `Blizzard Battle.net <https://battle.net/>`_: an online gaming platform
+
+* `Celestia <https://celestia.space/>`_: real-time 3D visualization of space
+
+* `Ceph <https://ceph.com/>`_: a scalable distributed storage system
+
+* `ccache <https://ccache.dev/>`_: a compiler cache
+
+* `ClickHouse <https://github.com/ClickHouse/ClickHouse>`_: analytical database
+ management system
+
+* `CUAUV <https://cuauv.org/>`_: Cornell University's autonomous underwater
+ vehicle
+
+* `Drake <https://drake.mit.edu/>`_: a planning, control, and analysis toolbox
+ for nonlinear dynamical systems (MIT)
+
+* `Envoy <https://lyft.github.io/envoy/>`_: C++ L7 proxy and communication bus
+ (Lyft)
+
+* `FiveM <https://fivem.net/>`_: a modification framework for GTA V
+
+* `fmtlog <https://github.com/MengRao/fmtlog>`_: a performant fmtlib-style
+ logging library with latency in nanoseconds
+
+* `Folly <https://github.com/facebook/folly>`_: Facebook open-source library
+
+* `Grand Mountain Adventure
+ <https://store.steampowered.com/app/1247360/Grand_Mountain_Adventure/>`_:
+ A beautiful open-world ski & snowboarding game
+
+* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
+ Player vs Player Gaming Network with tweaks
+
+* `KBEngine <https://github.com/kbengine/kbengine>`_: an open-source MMOG server
+ engine
+
+* `Keypirinha <https://keypirinha.com/>`_: a semantic launcher for Windows
+
+* `Kodi <https://kodi.tv/>`_ (formerly xbmc): home theater software
+
+* `Knuth <https://kth.cash/>`_: high-performance Bitcoin full-node
+
+* `Microsoft Verona <https://github.com/microsoft/verona>`_:
+ research programming language for concurrent ownership
+
+* `MongoDB <https://mongodb.com/>`_: distributed document database
+
+* `MongoDB Smasher <https://github.com/duckie/mongo_smasher>`_: a small tool to
+ generate randomized datasets
+
+* `OpenSpace <https://openspaceproject.com/>`_: an open-source
+ astrovisualization framework
+
+* `PenUltima Online (POL) <https://www.polserver.com/>`_:
+ an MMO server, compatible with most Ultima Online clients
+
+* `PyTorch <https://github.com/pytorch/pytorch>`_: an open-source machine
+ learning library
+
+* `quasardb <https://www.quasardb.net/>`_: a distributed, high-performance,
+ associative database
+
+* `Quill <https://github.com/odygrd/quill>`_: asynchronous low-latency logging library
+
+* `QKW <https://github.com/ravijanjam/qkw>`_: generalizing aliasing to simplify
+ navigation, and executing complex multi-line terminal command sequences
+
+* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: a Redis cluster
+ proxy
+
+* `redpanda <https://vectorized.io/redpanda>`_: a 10x faster Kafka® replacement
+ for mission critical systems written in C++
+
+* `rpclib <http://rpclib.net/>`_: a modern C++ msgpack-RPC server and client
+ library
+
+* `Salesforce Analytics Cloud
+ <https://www.salesforce.com/analytics-cloud/overview/>`_:
+ business intelligence software
+
+* `Scylla <https://www.scylladb.com/>`_: a Cassandra-compatible NoSQL data store
+ that can handle 1 million transactions per second on a single server
+
+* `Seastar <http://www.seastar-project.org/>`_: an advanced, open-source C++
+ framework for high-performance server applications on modern hardware
+
+* `spdlog <https://github.com/gabime/spdlog>`_: super fast C++ logging library
+
+* `Stellar <https://www.stellar.org/>`_: financial platform
+
+* `Touch Surgery <https://www.touchsurgery.com/>`_: surgery simulator
+
+* `TrinityCore <https://github.com/TrinityCore/TrinityCore>`_: open-source
+ MMORPG framework
+
+* `Windows Terminal <https://github.com/microsoft/terminal>`_: the new Windows
+ terminal
+
+`More... <https://github.com/search?q=fmtlib&type=Code>`_
+
+If you are aware of other projects using this library, please let me know
+by `email <mailto:victor.zverovich@gmail.com>`_ or by submitting an
+`issue <https://github.com/fmtlib/fmt/issues>`_.
+
+Motivation
+----------
+
+So why yet another formatting library?
+
+There are plenty of methods for doing this task, from standard ones like
+the printf family of function and iostreams to Boost Format and FastFormat
+libraries. The reason for creating a new library is that every existing
+solution that I found either had serious issues or didn't provide
+all the features I needed.
+
+printf
+~~~~~~
+
+The good thing about ``printf`` is that it is pretty fast and readily available
+being a part of the C standard library. The main drawback is that it
+doesn't support user-defined types. ``printf`` also has safety issues although
+they are somewhat mitigated with `__attribute__ ((format (printf, ...))
+<https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
+There is a POSIX extension that adds positional arguments required for
+`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
+to ``printf`` but it is not a part of C99 and may not be available on some
+platforms.
+
+iostreams
+~~~~~~~~~
+
+The main issue with iostreams is best illustrated with an example:
+
+.. code:: c++
+
+ std::cout << std::setprecision(2) << std::fixed << 1.23456 << "\n";
+
+which is a lot of typing compared to printf:
+
+.. code:: c++
+
+ printf("%.2f\n", 1.23456);
+
+Matthew Wilson, the author of FastFormat, called this "chevron hell". iostreams
+don't support positional arguments by design.
+
+The good part is that iostreams support user-defined types and are safe although
+error handling is awkward.
+
+Boost Format
+~~~~~~~~~~~~
+
+This is a very powerful library which supports both ``printf``-like format
+strings and positional arguments. Its main drawback is performance. According to
+various benchmarks, it is much slower than other methods considered here. Boost
+Format also has excessive build times and severe code bloat issues (see
+`Benchmarks`_).
+
+FastFormat
+~~~~~~~~~~
+
+This is an interesting library which is fast, safe and has positional arguments.
+However, it has significant limitations, citing its author:
+
+ Three features that have no hope of being accommodated within the
+ current design are:
+
+ * Leading zeros (or any other non-space padding)
+ * Octal/hexadecimal encoding
+ * Runtime width/alignment specification
+
+It is also quite big and has a heavy dependency, STLSoft, which might be too
+restrictive for using it in some projects.
+
+Boost Spirit.Karma
+~~~~~~~~~~~~~~~~~~
+
+This is not really a formatting library but I decided to include it here for
+completeness. As iostreams, it suffers from the problem of mixing verbatim text
+with arguments. The library is pretty fast, but slower on integer formatting
+than ``fmt::format_to`` with format string compilation on Karma's own benchmark,
+see `Converting a hundred million integers to strings per second
+<http://www.zverovich.net/2020/06/13/fast-int-to-string-revisited.html>`_.
+
+License
+-------
+
+{fmt} is distributed under the MIT `license
+<https://github.com/fmtlib/fmt/blob/master/LICENSE.rst>`_.
+
+Documentation License
+---------------------
+
+The `Format String Syntax <https://fmt.dev/latest/syntax.html>`_
+section in the documentation is based on the one from Python `string module
+documentation <https://docs.python.org/3/library/string.html#module-string>`_.
+For this reason the documentation is distributed under the Python Software
+Foundation license available in `doc/python-license.txt
+<https://raw.github.com/fmtlib/fmt/master/doc/python-license.txt>`_.
+It only applies if you distribute the documentation of {fmt}.
+
+Maintainers
+-----------
+
+The {fmt} library is maintained by Victor Zverovich (`vitaut
+<https://github.com/vitaut>`_) and Jonathan Müller (`foonathan
+<https://github.com/foonathan>`_) with contributions from many other people.
+See `Contributors <https://github.com/fmtlib/fmt/graphs/contributors>`_ and
+`Releases <https://github.com/fmtlib/fmt/releases>`_ for some of the names.
+Let us know if your contribution is not listed or mentioned incorrectly and
+we'll make it right.
diff --git a/extern/fmtlib/include/fmt/core.h b/extern/fmtlib/include/fmt/core.h
new file mode 100644
index 00000000000..92a7aa1df69
--- /dev/null
+++ b/extern/fmtlib/include/fmt/core.h
@@ -0,0 +1,3236 @@
+// Formatting library for C++ - the core API for char/UTF-8
+//
+// Copyright (c) 2012 - present, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_CORE_H_
+#define FMT_CORE_H_
+
+#include <cstddef> // std::byte
+#include <cstdio> // std::FILE
+#include <cstring>
+#include <iterator>
+#include <limits>
+#include <string>
+#include <type_traits>
+
+// The fmt library version in the form major * 10000 + minor * 100 + patch.
+#define FMT_VERSION 80101
+
+#if defined(__clang__) && !defined(__ibmxl__)
+# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__)
+#else
+# define FMT_CLANG_VERSION 0
+#endif
+
+#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && \
+ !defined(__NVCOMPILER)
+# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+#else
+# define FMT_GCC_VERSION 0
+#endif
+
+#ifndef FMT_GCC_PRAGMA
+// Workaround _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884.
+# if FMT_GCC_VERSION >= 504
+# define FMT_GCC_PRAGMA(arg) _Pragma(arg)
+# else
+# define FMT_GCC_PRAGMA(arg)
+# endif
+#endif
+
+#ifdef __ICL
+# define FMT_ICC_VERSION __ICL
+#elif defined(__INTEL_COMPILER)
+# define FMT_ICC_VERSION __INTEL_COMPILER
+#else
+# define FMT_ICC_VERSION 0
+#endif
+
+#ifdef __NVCC__
+# define FMT_NVCC __NVCC__
+#else
+# define FMT_NVCC 0
+#endif
+
+#ifdef _MSC_VER
+# define FMT_MSC_VER _MSC_VER
+# define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__))
+#else
+# define FMT_MSC_VER 0
+# define FMT_MSC_WARNING(...)
+#endif
+
+#ifdef __has_feature
+# define FMT_HAS_FEATURE(x) __has_feature(x)
+#else
+# define FMT_HAS_FEATURE(x) 0
+#endif
+
+#if defined(__has_include) && \
+ (!defined(__INTELLISENSE__) || FMT_MSC_VER > 1900) && \
+ (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600)
+# define FMT_HAS_INCLUDE(x) __has_include(x)
+#else
+# define FMT_HAS_INCLUDE(x) 0
+#endif
+
+#ifdef __has_cpp_attribute
+# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
+#else
+# define FMT_HAS_CPP_ATTRIBUTE(x) 0
+#endif
+
+#ifdef _MSVC_LANG
+# define FMT_CPLUSPLUS _MSVC_LANG
+#else
+# define FMT_CPLUSPLUS __cplusplus
+#endif
+
+#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \
+ (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute))
+
+#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \
+ (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute))
+
+// Check if relaxed C++14 constexpr is supported.
+// GCC doesn't allow throw in constexpr until version 6 (bug 67371).
+#ifndef FMT_USE_CONSTEXPR
+# define FMT_USE_CONSTEXPR \
+ (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1912 || \
+ (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \
+ !FMT_NVCC && !FMT_ICC_VERSION
+#endif
+#if FMT_USE_CONSTEXPR
+# define FMT_CONSTEXPR constexpr
+# define FMT_CONSTEXPR_DECL constexpr
+#else
+# define FMT_CONSTEXPR
+# define FMT_CONSTEXPR_DECL
+#endif
+
+#if ((__cplusplus >= 202002L) && \
+ (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \
+ (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002)
+# define FMT_CONSTEXPR20 constexpr
+#else
+# define FMT_CONSTEXPR20
+#endif
+
+// Check if constexpr std::char_traits<>::compare,length is supported.
+#if defined(__GLIBCXX__)
+# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \
+ _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE.
+# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
+# endif
+#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \
+ _LIBCPP_VERSION >= 4000
+# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
+#elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L
+# define FMT_CONSTEXPR_CHAR_TRAITS constexpr
+#endif
+#ifndef FMT_CONSTEXPR_CHAR_TRAITS
+# define FMT_CONSTEXPR_CHAR_TRAITS
+#endif
+
+// Check if exceptions are disabled.
+#ifndef FMT_EXCEPTIONS
+# if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \
+ FMT_MSC_VER && !_HAS_EXCEPTIONS
+# define FMT_EXCEPTIONS 0
+# else
+# define FMT_EXCEPTIONS 1
+# endif
+#endif
+
+// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature).
+#ifndef FMT_USE_NOEXCEPT
+# define FMT_USE_NOEXCEPT 0
+#endif
+
+#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \
+ FMT_GCC_VERSION >= 408 || FMT_MSC_VER >= 1900
+# define FMT_DETECTED_NOEXCEPT noexcept
+# define FMT_HAS_CXX11_NOEXCEPT 1
+#else
+# define FMT_DETECTED_NOEXCEPT throw()
+# define FMT_HAS_CXX11_NOEXCEPT 0
+#endif
+
+#ifndef FMT_NOEXCEPT
+# if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT
+# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT
+# else
+# define FMT_NOEXCEPT
+# endif
+#endif
+
+// [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code
+// warnings.
+#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \
+ !FMT_NVCC
+# define FMT_NORETURN [[noreturn]]
+#else
+# define FMT_NORETURN
+#endif
+
+#if __cplusplus == 201103L || __cplusplus == 201402L
+# if defined(__INTEL_COMPILER) || defined(__PGI)
+# define FMT_FALLTHROUGH
+# elif defined(__clang__)
+# define FMT_FALLTHROUGH [[clang::fallthrough]]
+# elif FMT_GCC_VERSION >= 700 && \
+ (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
+# define FMT_FALLTHROUGH [[gnu::fallthrough]]
+# else
+# define FMT_FALLTHROUGH
+# endif
+#elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough)
+# define FMT_FALLTHROUGH [[fallthrough]]
+#else
+# define FMT_FALLTHROUGH
+#endif
+
+#ifndef FMT_NODISCARD
+# if FMT_HAS_CPP17_ATTRIBUTE(nodiscard)
+# define FMT_NODISCARD [[nodiscard]]
+# else
+# define FMT_NODISCARD
+# endif
+#endif
+
+#ifndef FMT_USE_FLOAT
+# define FMT_USE_FLOAT 1
+#endif
+#ifndef FMT_USE_DOUBLE
+# define FMT_USE_DOUBLE 1
+#endif
+#ifndef FMT_USE_LONG_DOUBLE
+# define FMT_USE_LONG_DOUBLE 1
+#endif
+
+#ifndef FMT_INLINE
+# if FMT_GCC_VERSION || FMT_CLANG_VERSION
+# define FMT_INLINE inline __attribute__((always_inline))
+# else
+# define FMT_INLINE inline
+# endif
+#endif
+
+#ifndef FMT_DEPRECATED
+# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900
+# define FMT_DEPRECATED [[deprecated]]
+# else
+# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__)
+# define FMT_DEPRECATED __attribute__((deprecated))
+# elif FMT_MSC_VER
+# define FMT_DEPRECATED __declspec(deprecated)
+# else
+# define FMT_DEPRECATED /* deprecated */
+# endif
+# endif
+#endif
+
+#ifndef FMT_BEGIN_NAMESPACE
+# define FMT_BEGIN_NAMESPACE \
+ namespace fmt { \
+ inline namespace v8 {
+# define FMT_END_NAMESPACE \
+ } \
+ }
+#endif
+
+#ifndef FMT_MODULE_EXPORT
+# define FMT_MODULE_EXPORT
+# define FMT_MODULE_EXPORT_BEGIN
+# define FMT_MODULE_EXPORT_END
+# define FMT_BEGIN_DETAIL_NAMESPACE namespace detail {
+# define FMT_END_DETAIL_NAMESPACE }
+#endif
+
+#if !defined(FMT_HEADER_ONLY) && defined(_WIN32)
+# define FMT_CLASS_API FMT_MSC_WARNING(suppress : 4275)
+# ifdef FMT_EXPORT
+# define FMT_API __declspec(dllexport)
+# elif defined(FMT_SHARED)
+# define FMT_API __declspec(dllimport)
+# endif
+#else
+# define FMT_CLASS_API
+# if defined(FMT_EXPORT) || defined(FMT_SHARED)
+# if defined(__GNUC__) || defined(__clang__)
+# define FMT_API __attribute__((visibility("default")))
+# endif
+# endif
+#endif
+#ifndef FMT_API
+# define FMT_API
+#endif
+
+// libc++ supports string_view in pre-c++17.
+#if (FMT_HAS_INCLUDE(<string_view>) && \
+ (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \
+ (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910)
+# include <string_view>
+# define FMT_USE_STRING_VIEW
+#elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L
+# include <experimental/string_view>
+# define FMT_USE_EXPERIMENTAL_STRING_VIEW
+#endif
+
+#ifndef FMT_UNICODE
+# define FMT_UNICODE !FMT_MSC_VER
+#endif
+
+#ifndef FMT_CONSTEVAL
+# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \
+ __cplusplus > 201703L && !defined(__apple_build_version__)) || \
+ (defined(__cpp_consteval) && \
+ (!FMT_MSC_VER || _MSC_FULL_VER >= 193030704))
+// consteval is broken in MSVC before VS2022 and Apple clang 13.
+# define FMT_CONSTEVAL consteval
+# define FMT_HAS_CONSTEVAL
+# else
+# define FMT_CONSTEVAL
+# endif
+#endif
+
+#ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+# if defined(__cpp_nontype_template_args) && \
+ ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \
+ __cpp_nontype_template_args >= 201911L)
+# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1
+# else
+# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0
+# endif
+#endif
+
+// Enable minimal optimizations for more compact code in debug mode.
+FMT_GCC_PRAGMA("GCC push_options")
+#ifndef __OPTIMIZE__
+FMT_GCC_PRAGMA("GCC optimize(\"Og\")")
+#endif
+
+FMT_BEGIN_NAMESPACE
+FMT_MODULE_EXPORT_BEGIN
+
+// Implementations of enable_if_t and other metafunctions for older systems.
+template <bool B, typename T = void>
+using enable_if_t = typename std::enable_if<B, T>::type;
+template <bool B, typename T, typename F>
+using conditional_t = typename std::conditional<B, T, F>::type;
+template <bool B> using bool_constant = std::integral_constant<bool, B>;
+template <typename T>
+using remove_reference_t = typename std::remove_reference<T>::type;
+template <typename T>
+using remove_const_t = typename std::remove_const<T>::type;
+template <typename T>
+using remove_cvref_t = typename std::remove_cv<remove_reference_t<T>>::type;
+template <typename T> struct type_identity { using type = T; };
+template <typename T> using type_identity_t = typename type_identity<T>::type;
+
+struct monostate {
+ constexpr monostate() {}
+};
+
+// An enable_if helper to be used in template parameters which results in much
+// shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed
+// to workaround a bug in MSVC 2019 (see #1140 and #1186).
+#ifdef FMT_DOC
+# define FMT_ENABLE_IF(...)
+#else
+# define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0
+#endif
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+// Suppress "unused variable" warnings with the method described in
+// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/.
+// (void)var does not work on many Intel compilers.
+template <typename... T> FMT_CONSTEXPR void ignore_unused(const T&...) {}
+
+constexpr FMT_INLINE auto is_constant_evaluated(bool default_value = false)
+ FMT_NOEXCEPT -> bool {
+#ifdef __cpp_lib_is_constant_evaluated
+ ignore_unused(default_value);
+ return std::is_constant_evaluated();
+#else
+ return default_value;
+#endif
+}
+
+// A function to suppress "conditional expression is constant" warnings.
+template <typename T> constexpr FMT_INLINE auto const_check(T value) -> T {
+ return value;
+}
+
+FMT_NORETURN FMT_API void assert_fail(const char* file, int line,
+ const char* message);
+
+#ifndef FMT_ASSERT
+# ifdef NDEBUG
+// FMT_ASSERT is not empty to avoid -Werror=empty-body.
+# define FMT_ASSERT(condition, message) \
+ ::fmt::detail::ignore_unused((condition), (message))
+# else
+# define FMT_ASSERT(condition, message) \
+ ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \
+ ? (void)0 \
+ : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message)))
+# endif
+#endif
+
+#ifdef __cpp_lib_byte
+using byte = std::byte;
+#else
+enum class byte : unsigned char {};
+#endif
+
+#if defined(FMT_USE_STRING_VIEW)
+template <typename Char> using std_string_view = std::basic_string_view<Char>;
+#elif defined(FMT_USE_EXPERIMENTAL_STRING_VIEW)
+template <typename Char>
+using std_string_view = std::experimental::basic_string_view<Char>;
+#else
+template <typename T> struct std_string_view {};
+#endif
+
+#ifdef FMT_USE_INT128
+// Do nothing.
+#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \
+ !(FMT_CLANG_VERSION && FMT_MSC_VER)
+# define FMT_USE_INT128 1
+using int128_t = __int128_t;
+using uint128_t = __uint128_t;
+template <typename T> inline auto convert_for_visit(T value) -> T {
+ return value;
+}
+#else
+# define FMT_USE_INT128 0
+#endif
+#if !FMT_USE_INT128
+enum class int128_t {};
+enum class uint128_t {};
+// Reduce template instantiations.
+template <typename T> inline auto convert_for_visit(T) -> monostate {
+ return {};
+}
+#endif
+
+// Casts a nonnegative integer to unsigned.
+template <typename Int>
+FMT_CONSTEXPR auto to_unsigned(Int value) ->
+ typename std::make_unsigned<Int>::type {
+ FMT_ASSERT(value >= 0, "negative value");
+ return static_cast<typename std::make_unsigned<Int>::type>(value);
+}
+
+FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5";
+
+constexpr auto is_utf8() -> bool {
+ // Avoid buggy sign extensions in MSVC's constant evaluation mode.
+ // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612
+ using uchar = unsigned char;
+ return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 &&
+ uchar(micro[1]) == 0xB5);
+}
+FMT_END_DETAIL_NAMESPACE
+
+/**
+ An implementation of ``std::basic_string_view`` for pre-C++17. It provides a
+ subset of the API. ``fmt::basic_string_view`` is used for format strings even
+ if ``std::string_view`` is available to prevent issues when a library is
+ compiled with a different ``-std`` option than the client code (which is not
+ recommended).
+ */
+template <typename Char> class basic_string_view {
+ private:
+ const Char* data_;
+ size_t size_;
+
+ public:
+ using value_type = Char;
+ using iterator = const Char*;
+
+ constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {}
+
+ /** Constructs a string reference object from a C string and a size. */
+ constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT
+ : data_(s),
+ size_(count) {}
+
+ /**
+ \rst
+ Constructs a string reference object from a C string computing
+ the size with ``std::char_traits<Char>::length``.
+ \endrst
+ */
+ FMT_CONSTEXPR_CHAR_TRAITS
+ FMT_INLINE
+ basic_string_view(const Char* s)
+ : data_(s),
+ size_(detail::const_check(std::is_same<Char, char>::value &&
+ !detail::is_constant_evaluated(true))
+ ? std::strlen(reinterpret_cast<const char*>(s))
+ : std::char_traits<Char>::length(s)) {}
+
+ /** Constructs a string reference from a ``std::basic_string`` object. */
+ template <typename Traits, typename Alloc>
+ FMT_CONSTEXPR basic_string_view(
+ const std::basic_string<Char, Traits, Alloc>& s) FMT_NOEXCEPT
+ : data_(s.data()),
+ size_(s.size()) {}
+
+ template <typename S, FMT_ENABLE_IF(std::is_same<
+ S, detail::std_string_view<Char>>::value)>
+ FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()),
+ size_(s.size()) {}
+
+ /** Returns a pointer to the string data. */
+ constexpr auto data() const FMT_NOEXCEPT -> const Char* { return data_; }
+
+ /** Returns the string size. */
+ constexpr auto size() const FMT_NOEXCEPT -> size_t { return size_; }
+
+ constexpr auto begin() const FMT_NOEXCEPT -> iterator { return data_; }
+ constexpr auto end() const FMT_NOEXCEPT -> iterator { return data_ + size_; }
+
+ constexpr auto operator[](size_t pos) const FMT_NOEXCEPT -> const Char& {
+ return data_[pos];
+ }
+
+ FMT_CONSTEXPR void remove_prefix(size_t n) FMT_NOEXCEPT {
+ data_ += n;
+ size_ -= n;
+ }
+
+ // Lexicographically compare this string reference to other.
+ FMT_CONSTEXPR_CHAR_TRAITS auto compare(basic_string_view other) const -> int {
+ size_t str_size = size_ < other.size_ ? size_ : other.size_;
+ int result = std::char_traits<Char>::compare(data_, other.data_, str_size);
+ if (result == 0)
+ result = size_ == other.size_ ? 0 : (size_ < other.size_ ? -1 : 1);
+ return result;
+ }
+
+ FMT_CONSTEXPR_CHAR_TRAITS friend auto operator==(basic_string_view lhs,
+ basic_string_view rhs)
+ -> bool {
+ return lhs.compare(rhs) == 0;
+ }
+ friend auto operator!=(basic_string_view lhs, basic_string_view rhs) -> bool {
+ return lhs.compare(rhs) != 0;
+ }
+ friend auto operator<(basic_string_view lhs, basic_string_view rhs) -> bool {
+ return lhs.compare(rhs) < 0;
+ }
+ friend auto operator<=(basic_string_view lhs, basic_string_view rhs) -> bool {
+ return lhs.compare(rhs) <= 0;
+ }
+ friend auto operator>(basic_string_view lhs, basic_string_view rhs) -> bool {
+ return lhs.compare(rhs) > 0;
+ }
+ friend auto operator>=(basic_string_view lhs, basic_string_view rhs) -> bool {
+ return lhs.compare(rhs) >= 0;
+ }
+};
+
+using string_view = basic_string_view<char>;
+
+/** Specifies if ``T`` is a character type. Can be specialized by users. */
+template <typename T> struct is_char : std::false_type {};
+template <> struct is_char<char> : std::true_type {};
+
+// Returns a string view of `s`.
+template <typename Char, FMT_ENABLE_IF(is_char<Char>::value)>
+FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view<Char> {
+ return s;
+}
+template <typename Char, typename Traits, typename Alloc>
+inline auto to_string_view(const std::basic_string<Char, Traits, Alloc>& s)
+ -> basic_string_view<Char> {
+ return s;
+}
+template <typename Char>
+constexpr auto to_string_view(basic_string_view<Char> s)
+ -> basic_string_view<Char> {
+ return s;
+}
+template <typename Char,
+ FMT_ENABLE_IF(!std::is_empty<detail::std_string_view<Char>>::value)>
+inline auto to_string_view(detail::std_string_view<Char> s)
+ -> basic_string_view<Char> {
+ return s;
+}
+
+// A base class for compile-time strings. It is defined in the fmt namespace to
+// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42).
+struct compile_string {};
+
+template <typename S>
+struct is_compile_string : std::is_base_of<compile_string, S> {};
+
+template <typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
+constexpr auto to_string_view(const S& s)
+ -> basic_string_view<typename S::char_type> {
+ return basic_string_view<typename S::char_type>(s);
+}
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+void to_string_view(...);
+using fmt::to_string_view;
+
+// Specifies whether S is a string type convertible to fmt::basic_string_view.
+// It should be a constexpr function but MSVC 2017 fails to compile it in
+// enable_if and MSVC 2015 fails to compile it as an alias template.
+template <typename S>
+struct is_string : std::is_class<decltype(to_string_view(std::declval<S>()))> {
+};
+
+template <typename S, typename = void> struct char_t_impl {};
+template <typename S> struct char_t_impl<S, enable_if_t<is_string<S>::value>> {
+ using result = decltype(to_string_view(std::declval<S>()));
+ using type = typename result::value_type;
+};
+
+// Reports a compile-time error if S is not a valid format string.
+template <typename..., typename S, FMT_ENABLE_IF(!is_compile_string<S>::value)>
+FMT_INLINE void check_format_string(const S&) {
+#ifdef FMT_ENFORCE_COMPILE_STRING
+ static_assert(is_compile_string<S>::value,
+ "FMT_ENFORCE_COMPILE_STRING requires all format strings to use "
+ "FMT_STRING.");
+#endif
+}
+template <typename..., typename S, FMT_ENABLE_IF(is_compile_string<S>::value)>
+void check_format_string(S);
+
+FMT_NORETURN FMT_API void throw_format_error(const char* message);
+
+struct error_handler {
+ constexpr error_handler() = default;
+ constexpr error_handler(const error_handler&) = default;
+
+ // This function is intentionally not constexpr to give a compile-time error.
+ FMT_NORETURN FMT_API void on_error(const char* message);
+};
+FMT_END_DETAIL_NAMESPACE
+
+/** String's character type. */
+template <typename S> using char_t = typename detail::char_t_impl<S>::type;
+
+/**
+ \rst
+ Parsing context consisting of a format string range being parsed and an
+ argument counter for automatic indexing.
+ You can use the ``format_parse_context`` type alias for ``char`` instead.
+ \endrst
+ */
+template <typename Char, typename ErrorHandler = detail::error_handler>
+class basic_format_parse_context : private ErrorHandler {
+ private:
+ basic_string_view<Char> format_str_;
+ int next_arg_id_;
+
+ public:
+ using char_type = Char;
+ using iterator = typename basic_string_view<Char>::iterator;
+
+ explicit constexpr basic_format_parse_context(
+ basic_string_view<Char> format_str, ErrorHandler eh = {},
+ int next_arg_id = 0)
+ : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {}
+
+ /**
+ Returns an iterator to the beginning of the format string range being
+ parsed.
+ */
+ constexpr auto begin() const FMT_NOEXCEPT -> iterator {
+ return format_str_.begin();
+ }
+
+ /**
+ Returns an iterator past the end of the format string range being parsed.
+ */
+ constexpr auto end() const FMT_NOEXCEPT -> iterator {
+ return format_str_.end();
+ }
+
+ /** Advances the begin iterator to ``it``. */
+ FMT_CONSTEXPR void advance_to(iterator it) {
+ format_str_.remove_prefix(detail::to_unsigned(it - begin()));
+ }
+
+ /**
+ Reports an error if using the manual argument indexing; otherwise returns
+ the next argument index and switches to the automatic indexing.
+ */
+ FMT_CONSTEXPR auto next_arg_id() -> int {
+ // Don't check if the argument id is valid to avoid overhead and because it
+ // will be checked during formatting anyway.
+ if (next_arg_id_ >= 0) return next_arg_id_++;
+ on_error("cannot switch from manual to automatic argument indexing");
+ return 0;
+ }
+
+ /**
+ Reports an error if using the automatic argument indexing; otherwise
+ switches to the manual indexing.
+ */
+ FMT_CONSTEXPR void check_arg_id(int) {
+ if (next_arg_id_ > 0)
+ on_error("cannot switch from automatic to manual argument indexing");
+ else
+ next_arg_id_ = -1;
+ }
+
+ FMT_CONSTEXPR void check_arg_id(basic_string_view<Char>) {}
+
+ FMT_CONSTEXPR void on_error(const char* message) {
+ ErrorHandler::on_error(message);
+ }
+
+ constexpr auto error_handler() const -> ErrorHandler { return *this; }
+};
+
+using format_parse_context = basic_format_parse_context<char>;
+
+template <typename Context> class basic_format_arg;
+template <typename Context> class basic_format_args;
+template <typename Context> class dynamic_format_arg_store;
+
+// A formatter for objects of type T.
+template <typename T, typename Char = char, typename Enable = void>
+struct formatter {
+ // A deleted default constructor indicates a disabled formatter.
+ formatter() = delete;
+};
+
+// Specifies if T has an enabled formatter specialization. A type can be
+// formattable even if it doesn't have a formatter e.g. via a conversion.
+template <typename T, typename Context>
+using has_formatter =
+ std::is_constructible<typename Context::template formatter_type<T>>;
+
+// Checks whether T is a container with contiguous storage.
+template <typename T> struct is_contiguous : std::false_type {};
+template <typename Char>
+struct is_contiguous<std::basic_string<Char>> : std::true_type {};
+
+class appender;
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+template <typename Context, typename T>
+constexpr auto has_const_formatter_impl(T*)
+ -> decltype(typename Context::template formatter_type<T>().format(
+ std::declval<const T&>(), std::declval<Context&>()),
+ true) {
+ return true;
+}
+template <typename Context>
+constexpr auto has_const_formatter_impl(...) -> bool {
+ return false;
+}
+template <typename T, typename Context>
+constexpr auto has_const_formatter() -> bool {
+ return has_const_formatter_impl<Context>(static_cast<T*>(nullptr));
+}
+
+// Extracts a reference to the container from back_insert_iterator.
+template <typename Container>
+inline auto get_container(std::back_insert_iterator<Container> it)
+ -> Container& {
+ using bi_iterator = std::back_insert_iterator<Container>;
+ struct accessor : bi_iterator {
+ accessor(bi_iterator iter) : bi_iterator(iter) {}
+ using bi_iterator::container;
+ };
+ return *accessor(it).container;
+}
+
+template <typename Char, typename InputIt, typename OutputIt>
+FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out)
+ -> OutputIt {
+ while (begin != end) *out++ = static_cast<Char>(*begin++);
+ return out;
+}
+
+template <typename Char, typename T, typename U,
+ FMT_ENABLE_IF(
+ std::is_same<remove_const_t<T>, U>::value&& is_char<U>::value)>
+FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* {
+ if (is_constant_evaluated()) return copy_str<Char, T*, U*>(begin, end, out);
+ auto size = to_unsigned(end - begin);
+ memcpy(out, begin, size * sizeof(U));
+ return out + size;
+}
+
+/**
+ \rst
+ A contiguous memory buffer with an optional growing ability. It is an internal
+ class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`.
+ \endrst
+ */
+template <typename T> class buffer {
+ private:
+ T* ptr_;
+ size_t size_;
+ size_t capacity_;
+
+ protected:
+ // Don't initialize ptr_ since it is not accessed to save a few cycles.
+ FMT_MSC_WARNING(suppress : 26495)
+ buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {}
+
+ FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0,
+ size_t cap = 0) FMT_NOEXCEPT : ptr_(p),
+ size_(sz),
+ capacity_(cap) {}
+
+ FMT_CONSTEXPR20 ~buffer() = default;
+ buffer(buffer&&) = default;
+
+ /** Sets the buffer data and capacity. */
+ FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) FMT_NOEXCEPT {
+ ptr_ = buf_data;
+ capacity_ = buf_capacity;
+ }
+
+ /** Increases the buffer capacity to hold at least *capacity* elements. */
+ virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0;
+
+ public:
+ using value_type = T;
+ using const_reference = const T&;
+
+ buffer(const buffer&) = delete;
+ void operator=(const buffer&) = delete;
+
+ auto begin() FMT_NOEXCEPT -> T* { return ptr_; }
+ auto end() FMT_NOEXCEPT -> T* { return ptr_ + size_; }
+
+ auto begin() const FMT_NOEXCEPT -> const T* { return ptr_; }
+ auto end() const FMT_NOEXCEPT -> const T* { return ptr_ + size_; }
+
+ /** Returns the size of this buffer. */
+ constexpr auto size() const FMT_NOEXCEPT -> size_t { return size_; }
+
+ /** Returns the capacity of this buffer. */
+ constexpr auto capacity() const FMT_NOEXCEPT -> size_t { return capacity_; }
+
+ /** Returns a pointer to the buffer data. */
+ FMT_CONSTEXPR auto data() FMT_NOEXCEPT -> T* { return ptr_; }
+
+ /** Returns a pointer to the buffer data. */
+ FMT_CONSTEXPR auto data() const FMT_NOEXCEPT -> const T* { return ptr_; }
+
+ /** Clears this buffer. */
+ void clear() { size_ = 0; }
+
+ // Tries resizing the buffer to contain *count* elements. If T is a POD type
+ // the new elements may not be initialized.
+ FMT_CONSTEXPR20 void try_resize(size_t count) {
+ try_reserve(count);
+ size_ = count <= capacity_ ? count : capacity_;
+ }
+
+ // Tries increasing the buffer capacity to *new_capacity*. It can increase the
+ // capacity by a smaller amount than requested but guarantees there is space
+ // for at least one additional element either by increasing the capacity or by
+ // flushing the buffer if it is full.
+ FMT_CONSTEXPR20 void try_reserve(size_t new_capacity) {
+ if (new_capacity > capacity_) grow(new_capacity);
+ }
+
+ FMT_CONSTEXPR20 void push_back(const T& value) {
+ try_reserve(size_ + 1);
+ ptr_[size_++] = value;
+ }
+
+ /** Appends data to the end of the buffer. */
+ template <typename U> void append(const U* begin, const U* end);
+
+ template <typename I> FMT_CONSTEXPR auto operator[](I index) -> T& {
+ return ptr_[index];
+ }
+ template <typename I>
+ FMT_CONSTEXPR auto operator[](I index) const -> const T& {
+ return ptr_[index];
+ }
+};
+
+struct buffer_traits {
+ explicit buffer_traits(size_t) {}
+ auto count() const -> size_t { return 0; }
+ auto limit(size_t size) -> size_t { return size; }
+};
+
+class fixed_buffer_traits {
+ private:
+ size_t count_ = 0;
+ size_t limit_;
+
+ public:
+ explicit fixed_buffer_traits(size_t limit) : limit_(limit) {}
+ auto count() const -> size_t { return count_; }
+ auto limit(size_t size) -> size_t {
+ size_t n = limit_ > count_ ? limit_ - count_ : 0;
+ count_ += size;
+ return size < n ? size : n;
+ }
+};
+
+// A buffer that writes to an output iterator when flushed.
+template <typename OutputIt, typename T, typename Traits = buffer_traits>
+class iterator_buffer final : public Traits, public buffer<T> {
+ private:
+ OutputIt out_;
+ enum { buffer_size = 256 };
+ T data_[buffer_size];
+
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t) override {
+ if (this->size() == buffer_size) flush();
+ }
+
+ void flush() {
+ auto size = this->size();
+ this->clear();
+ out_ = copy_str<T>(data_, data_ + this->limit(size), out_);
+ }
+
+ public:
+ explicit iterator_buffer(OutputIt out, size_t n = buffer_size)
+ : Traits(n), buffer<T>(data_, 0, buffer_size), out_(out) {}
+ iterator_buffer(iterator_buffer&& other)
+ : Traits(other), buffer<T>(data_, 0, buffer_size), out_(other.out_) {}
+ ~iterator_buffer() { flush(); }
+
+ auto out() -> OutputIt {
+ flush();
+ return out_;
+ }
+ auto count() const -> size_t { return Traits::count() + this->size(); }
+};
+
+template <typename T>
+class iterator_buffer<T*, T, fixed_buffer_traits> final
+ : public fixed_buffer_traits,
+ public buffer<T> {
+ private:
+ T* out_;
+ enum { buffer_size = 256 };
+ T data_[buffer_size];
+
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t) override {
+ if (this->size() == this->capacity()) flush();
+ }
+
+ void flush() {
+ size_t n = this->limit(this->size());
+ if (this->data() == out_) {
+ out_ += n;
+ this->set(data_, buffer_size);
+ }
+ this->clear();
+ }
+
+ public:
+ explicit iterator_buffer(T* out, size_t n = buffer_size)
+ : fixed_buffer_traits(n), buffer<T>(out, 0, n), out_(out) {}
+ iterator_buffer(iterator_buffer&& other)
+ : fixed_buffer_traits(other),
+ buffer<T>(std::move(other)),
+ out_(other.out_) {
+ if (this->data() != out_) {
+ this->set(data_, buffer_size);
+ this->clear();
+ }
+ }
+ ~iterator_buffer() { flush(); }
+
+ auto out() -> T* {
+ flush();
+ return out_;
+ }
+ auto count() const -> size_t {
+ return fixed_buffer_traits::count() + this->size();
+ }
+};
+
+template <typename T> class iterator_buffer<T*, T> final : public buffer<T> {
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t) override {}
+
+ public:
+ explicit iterator_buffer(T* out, size_t = 0) : buffer<T>(out, 0, ~size_t()) {}
+
+ auto out() -> T* { return &*this->end(); }
+};
+
+// A buffer that writes to a container with the contiguous storage.
+template <typename Container>
+class iterator_buffer<std::back_insert_iterator<Container>,
+ enable_if_t<is_contiguous<Container>::value,
+ typename Container::value_type>>
+ final : public buffer<typename Container::value_type> {
+ private:
+ Container& container_;
+
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t capacity) override {
+ container_.resize(capacity);
+ this->set(&container_[0], capacity);
+ }
+
+ public:
+ explicit iterator_buffer(Container& c)
+ : buffer<typename Container::value_type>(c.size()), container_(c) {}
+ explicit iterator_buffer(std::back_insert_iterator<Container> out, size_t = 0)
+ : iterator_buffer(get_container(out)) {}
+ auto out() -> std::back_insert_iterator<Container> {
+ return std::back_inserter(container_);
+ }
+};
+
+// A buffer that counts the number of code units written discarding the output.
+template <typename T = char> class counting_buffer final : public buffer<T> {
+ private:
+ enum { buffer_size = 256 };
+ T data_[buffer_size];
+ size_t count_ = 0;
+
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t) override {
+ if (this->size() != buffer_size) return;
+ count_ += this->size();
+ this->clear();
+ }
+
+ public:
+ counting_buffer() : buffer<T>(data_, 0, buffer_size) {}
+
+ auto count() -> size_t { return count_ + this->size(); }
+};
+
+template <typename T>
+using buffer_appender = conditional_t<std::is_same<T, char>::value, appender,
+ std::back_insert_iterator<buffer<T>>>;
+
+// Maps an output iterator to a buffer.
+template <typename T, typename OutputIt>
+auto get_buffer(OutputIt out) -> iterator_buffer<OutputIt, T> {
+ return iterator_buffer<OutputIt, T>(out);
+}
+
+template <typename Buffer>
+auto get_iterator(Buffer& buf) -> decltype(buf.out()) {
+ return buf.out();
+}
+template <typename T> auto get_iterator(buffer<T>& buf) -> buffer_appender<T> {
+ return buffer_appender<T>(buf);
+}
+
+template <typename T, typename Char = char, typename Enable = void>
+struct fallback_formatter {
+ fallback_formatter() = delete;
+};
+
+// Specifies if T has an enabled fallback_formatter specialization.
+template <typename T, typename Char>
+using has_fallback_formatter =
+ std::is_constructible<fallback_formatter<T, Char>>;
+
+struct view {};
+
+template <typename Char, typename T> struct named_arg : view {
+ const Char* name;
+ const T& value;
+ named_arg(const Char* n, const T& v) : name(n), value(v) {}
+};
+
+template <typename Char> struct named_arg_info {
+ const Char* name;
+ int id;
+};
+
+template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
+struct arg_data {
+ // args_[0].named_args points to named_args_ to avoid bloating format_args.
+ // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
+ T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)];
+ named_arg_info<Char> named_args_[NUM_NAMED_ARGS];
+
+ template <typename... U>
+ arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {}
+ arg_data(const arg_data& other) = delete;
+ auto args() const -> const T* { return args_ + 1; }
+ auto named_args() -> named_arg_info<Char>* { return named_args_; }
+};
+
+template <typename T, typename Char, size_t NUM_ARGS>
+struct arg_data<T, Char, NUM_ARGS, 0> {
+ // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning.
+ T args_[NUM_ARGS != 0 ? NUM_ARGS : +1];
+
+ template <typename... U>
+ FMT_CONSTEXPR FMT_INLINE arg_data(const U&... init) : args_{init...} {}
+ FMT_CONSTEXPR FMT_INLINE auto args() const -> const T* { return args_; }
+ FMT_CONSTEXPR FMT_INLINE auto named_args() -> std::nullptr_t {
+ return nullptr;
+ }
+};
+
+template <typename Char>
+inline void init_named_args(named_arg_info<Char>*, int, int) {}
+
+template <typename T> struct is_named_arg : std::false_type {};
+template <typename T> struct is_statically_named_arg : std::false_type {};
+
+template <typename T, typename Char>
+struct is_named_arg<named_arg<Char, T>> : std::true_type {};
+
+template <typename Char, typename T, typename... Tail,
+ FMT_ENABLE_IF(!is_named_arg<T>::value)>
+void init_named_args(named_arg_info<Char>* named_args, int arg_count,
+ int named_arg_count, const T&, const Tail&... args) {
+ init_named_args(named_args, arg_count + 1, named_arg_count, args...);
+}
+
+template <typename Char, typename T, typename... Tail,
+ FMT_ENABLE_IF(is_named_arg<T>::value)>
+void init_named_args(named_arg_info<Char>* named_args, int arg_count,
+ int named_arg_count, const T& arg, const Tail&... args) {
+ named_args[named_arg_count++] = {arg.name, arg_count};
+ init_named_args(named_args, arg_count + 1, named_arg_count, args...);
+}
+
+template <typename... Args>
+FMT_CONSTEXPR FMT_INLINE void init_named_args(std::nullptr_t, int, int,
+ const Args&...) {}
+
+template <bool B = false> constexpr auto count() -> size_t { return B ? 1 : 0; }
+template <bool B1, bool B2, bool... Tail> constexpr auto count() -> size_t {
+ return (B1 ? 1 : 0) + count<B2, Tail...>();
+}
+
+template <typename... Args> constexpr auto count_named_args() -> size_t {
+ return count<is_named_arg<Args>::value...>();
+}
+
+template <typename... Args>
+constexpr auto count_statically_named_args() -> size_t {
+ return count<is_statically_named_arg<Args>::value...>();
+}
+
+enum class type {
+ none_type,
+ // Integer types should go first,
+ int_type,
+ uint_type,
+ long_long_type,
+ ulong_long_type,
+ int128_type,
+ uint128_type,
+ bool_type,
+ char_type,
+ last_integer_type = char_type,
+ // followed by floating-point types.
+ float_type,
+ double_type,
+ long_double_type,
+ last_numeric_type = long_double_type,
+ cstring_type,
+ string_type,
+ pointer_type,
+ custom_type
+};
+
+// Maps core type T to the corresponding type enum constant.
+template <typename T, typename Char>
+struct type_constant : std::integral_constant<type, type::custom_type> {};
+
+#define FMT_TYPE_CONSTANT(Type, constant) \
+ template <typename Char> \
+ struct type_constant<Type, Char> \
+ : std::integral_constant<type, type::constant> {}
+
+FMT_TYPE_CONSTANT(int, int_type);
+FMT_TYPE_CONSTANT(unsigned, uint_type);
+FMT_TYPE_CONSTANT(long long, long_long_type);
+FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type);
+FMT_TYPE_CONSTANT(int128_t, int128_type);
+FMT_TYPE_CONSTANT(uint128_t, uint128_type);
+FMT_TYPE_CONSTANT(bool, bool_type);
+FMT_TYPE_CONSTANT(Char, char_type);
+FMT_TYPE_CONSTANT(float, float_type);
+FMT_TYPE_CONSTANT(double, double_type);
+FMT_TYPE_CONSTANT(long double, long_double_type);
+FMT_TYPE_CONSTANT(const Char*, cstring_type);
+FMT_TYPE_CONSTANT(basic_string_view<Char>, string_type);
+FMT_TYPE_CONSTANT(const void*, pointer_type);
+
+constexpr bool is_integral_type(type t) {
+ return t > type::none_type && t <= type::last_integer_type;
+}
+
+constexpr bool is_arithmetic_type(type t) {
+ return t > type::none_type && t <= type::last_numeric_type;
+}
+
+struct unformattable {};
+struct unformattable_char : unformattable {};
+struct unformattable_const : unformattable {};
+struct unformattable_pointer : unformattable {};
+
+template <typename Char> struct string_value {
+ const Char* data;
+ size_t size;
+};
+
+template <typename Char> struct named_arg_value {
+ const named_arg_info<Char>* data;
+ size_t size;
+};
+
+template <typename Context> struct custom_value {
+ using parse_context = typename Context::parse_context_type;
+ void* value;
+ void (*format)(void* arg, parse_context& parse_ctx, Context& ctx);
+};
+
+// A formatting argument value.
+template <typename Context> class value {
+ public:
+ using char_type = typename Context::char_type;
+
+ union {
+ monostate no_value;
+ int int_value;
+ unsigned uint_value;
+ long long long_long_value;
+ unsigned long long ulong_long_value;
+ int128_t int128_value;
+ uint128_t uint128_value;
+ bool bool_value;
+ char_type char_value;
+ float float_value;
+ double double_value;
+ long double long_double_value;
+ const void* pointer;
+ string_value<char_type> string;
+ custom_value<Context> custom;
+ named_arg_value<char_type> named_args;
+ };
+
+ constexpr FMT_INLINE value() : no_value() {}
+ constexpr FMT_INLINE value(int val) : int_value(val) {}
+ constexpr FMT_INLINE value(unsigned val) : uint_value(val) {}
+ constexpr FMT_INLINE value(long long val) : long_long_value(val) {}
+ constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {}
+ FMT_INLINE value(int128_t val) : int128_value(val) {}
+ FMT_INLINE value(uint128_t val) : uint128_value(val) {}
+ constexpr FMT_INLINE value(float val) : float_value(val) {}
+ constexpr FMT_INLINE value(double val) : double_value(val) {}
+ FMT_INLINE value(long double val) : long_double_value(val) {}
+ constexpr FMT_INLINE value(bool val) : bool_value(val) {}
+ constexpr FMT_INLINE value(char_type val) : char_value(val) {}
+ FMT_CONSTEXPR FMT_INLINE value(const char_type* val) {
+ string.data = val;
+ if (is_constant_evaluated()) string.size = {};
+ }
+ FMT_CONSTEXPR FMT_INLINE value(basic_string_view<char_type> val) {
+ string.data = val.data();
+ string.size = val.size();
+ }
+ FMT_INLINE value(const void* val) : pointer(val) {}
+ FMT_INLINE value(const named_arg_info<char_type>* args, size_t size)
+ : named_args{args, size} {}
+
+ template <typename T> FMT_CONSTEXPR FMT_INLINE value(T& val) {
+ using value_type = remove_cvref_t<T>;
+ custom.value = const_cast<value_type*>(&val);
+ // Get the formatter type through the context to allow different contexts
+ // have different extension points, e.g. `formatter<T>` for `format` and
+ // `printf_formatter<T>` for `printf`.
+ custom.format = format_custom_arg<
+ value_type,
+ conditional_t<has_formatter<value_type, Context>::value,
+ typename Context::template formatter_type<value_type>,
+ fallback_formatter<value_type, char_type>>>;
+ }
+ value(unformattable);
+ value(unformattable_char);
+ value(unformattable_const);
+ value(unformattable_pointer);
+
+ private:
+ // Formats an argument of a custom type, such as a user-defined class.
+ template <typename T, typename Formatter>
+ static void format_custom_arg(void* arg,
+ typename Context::parse_context_type& parse_ctx,
+ Context& ctx) {
+ auto f = Formatter();
+ parse_ctx.advance_to(f.parse(parse_ctx));
+ using qualified_type =
+ conditional_t<has_const_formatter<T, Context>(), const T, T>;
+ ctx.advance_to(f.format(*static_cast<qualified_type*>(arg), ctx));
+ }
+};
+
+template <typename Context, typename T>
+FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg<Context>;
+
+// To minimize the number of types we need to deal with, long is translated
+// either to int or to long long depending on its size.
+enum { long_short = sizeof(long) == sizeof(int) };
+using long_type = conditional_t<long_short, int, long long>;
+using ulong_type = conditional_t<long_short, unsigned, unsigned long long>;
+
+// Maps formatting arguments to core types.
+// arg_mapper reports errors by returning unformattable instead of using
+// static_assert because it's used in the is_formattable trait.
+template <typename Context> struct arg_mapper {
+ using char_type = typename Context::char_type;
+
+ FMT_CONSTEXPR FMT_INLINE auto map(signed char val) -> int { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(unsigned char val) -> unsigned {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(short val) -> int { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(unsigned short val) -> unsigned {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(int val) -> int { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(unsigned val) -> unsigned { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(long val) -> long_type { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(unsigned long val) -> ulong_type {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(long long val) -> long long { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(unsigned long long val)
+ -> unsigned long long {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(int128_t val) -> int128_t { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(uint128_t val) -> uint128_t { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; }
+
+ template <typename T, FMT_ENABLE_IF(std::is_same<T, char>::value ||
+ std::is_same<T, char_type>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type {
+ return val;
+ }
+ template <typename T, enable_if_t<(std::is_same<T, wchar_t>::value ||
+#ifdef __cpp_char8_t
+ std::is_same<T, char8_t>::value ||
+#endif
+ std::is_same<T, char16_t>::value ||
+ std::is_same<T, char32_t>::value) &&
+ !std::is_same<T, char_type>::value,
+ int> = 0>
+ FMT_CONSTEXPR FMT_INLINE auto map(T) -> unformattable_char {
+ return {};
+ }
+
+ FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(long double val) -> long double {
+ return val;
+ }
+
+ FMT_CONSTEXPR FMT_INLINE auto map(char_type* val) -> const char_type* {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* {
+ return val;
+ }
+ template <typename T,
+ FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
+ std::is_same<char_type, char_t<T>>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
+ -> basic_string_view<char_type> {
+ return to_string_view(val);
+ }
+ template <typename T,
+ FMT_ENABLE_IF(is_string<T>::value && !std::is_pointer<T>::value &&
+ !std::is_same<char_type, char_t<T>>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T&) -> unformattable_char {
+ return {};
+ }
+ template <typename T,
+ FMT_ENABLE_IF(
+ std::is_constructible<basic_string_view<char_type>, T>::value &&
+ !is_string<T>::value && !has_formatter<T, Context>::value &&
+ !has_fallback_formatter<T, char_type>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
+ -> basic_string_view<char_type> {
+ return basic_string_view<char_type>(val);
+ }
+ template <
+ typename T,
+ FMT_ENABLE_IF(
+ std::is_constructible<std_string_view<char_type>, T>::value &&
+ !std::is_constructible<basic_string_view<char_type>, T>::value &&
+ !is_string<T>::value && !has_formatter<T, Context>::value &&
+ !has_fallback_formatter<T, char_type>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
+ -> basic_string_view<char_type> {
+ return std_string_view<char_type>(val);
+ }
+
+ using cstring_result = conditional_t<std::is_same<char_type, char>::value,
+ const char*, unformattable_pointer>;
+
+ FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const signed char* val)
+ -> cstring_result {
+ return map(reinterpret_cast<const char*>(val));
+ }
+ FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const unsigned char* val)
+ -> cstring_result {
+ return map(reinterpret_cast<const char*>(val));
+ }
+ FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(signed char* val)
+ -> cstring_result {
+ return map(reinterpret_cast<const char*>(val));
+ }
+ FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(unsigned char* val)
+ -> cstring_result {
+ return map(reinterpret_cast<const char*>(val));
+ }
+
+ FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; }
+ FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* {
+ return val;
+ }
+ FMT_CONSTEXPR FMT_INLINE auto map(std::nullptr_t val) -> const void* {
+ return val;
+ }
+
+ // We use SFINAE instead of a const T* parameter to avoid conflicting with
+ // the C array overload.
+ template <
+ typename T,
+ FMT_ENABLE_IF(
+ std::is_member_pointer<T>::value ||
+ std::is_function<typename std::remove_pointer<T>::type>::value ||
+ (std::is_convertible<const T&, const void*>::value &&
+ !std::is_convertible<const T&, const char_type*>::value))>
+ FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer {
+ return {};
+ }
+
+ template <typename T, std::size_t N,
+ FMT_ENABLE_IF(!std::is_same<T, wchar_t>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] {
+ return values;
+ }
+
+ template <typename T,
+ FMT_ENABLE_IF(
+ std::is_enum<T>::value&& std::is_convertible<T, int>::value &&
+ !has_formatter<T, Context>::value &&
+ !has_fallback_formatter<T, char_type>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& val)
+ -> decltype(std::declval<arg_mapper>().map(
+ static_cast<typename std::underlying_type<T>::type>(val))) {
+ return map(static_cast<typename std::underlying_type<T>::type>(val));
+ }
+
+ FMT_CONSTEXPR FMT_INLINE auto map(detail::byte val) -> unsigned {
+ return map(static_cast<unsigned char>(val));
+ }
+
+ template <typename T, typename U = remove_cvref_t<T>>
+ struct formattable
+ : bool_constant<has_const_formatter<U, Context>() ||
+ !std::is_const<remove_reference_t<T>>::value ||
+ has_fallback_formatter<U, char_type>::value> {};
+
+#if FMT_MSC_VER != 0 && FMT_MSC_VER < 1910
+ // Workaround a bug in MSVC.
+ template <typename T> FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
+ return val;
+ }
+#else
+ template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
+ return val;
+ }
+ template <typename T, FMT_ENABLE_IF(!formattable<T>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto do_map(T&&) -> unformattable_const {
+ return {};
+ }
+#endif
+
+ template <typename T, typename U = remove_cvref_t<T>,
+ FMT_ENABLE_IF(!is_string<U>::value && !is_char<U>::value &&
+ !std::is_array<U>::value &&
+ (has_formatter<U, Context>::value ||
+ has_fallback_formatter<U, char_type>::value))>
+ FMT_CONSTEXPR FMT_INLINE auto map(T&& val)
+ -> decltype(this->do_map(std::forward<T>(val))) {
+ return do_map(std::forward<T>(val));
+ }
+
+ template <typename T, FMT_ENABLE_IF(is_named_arg<T>::value)>
+ FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg)
+ -> decltype(std::declval<arg_mapper>().map(named_arg.value)) {
+ return map(named_arg.value);
+ }
+
+ auto map(...) -> unformattable { return {}; }
+};
+
+// A type constant after applying arg_mapper<Context>.
+template <typename T, typename Context>
+using mapped_type_constant =
+ type_constant<decltype(arg_mapper<Context>().map(std::declval<const T&>())),
+ typename Context::char_type>;
+
+enum { packed_arg_bits = 4 };
+// Maximum number of arguments with packed types.
+enum { max_packed_args = 62 / packed_arg_bits };
+enum : unsigned long long { is_unpacked_bit = 1ULL << 63 };
+enum : unsigned long long { has_named_args_bit = 1ULL << 62 };
+
+FMT_END_DETAIL_NAMESPACE
+
+// An output iterator that appends to a buffer.
+// It is used to reduce symbol sizes for the common case.
+class appender : public std::back_insert_iterator<detail::buffer<char>> {
+ using base = std::back_insert_iterator<detail::buffer<char>>;
+
+ template <typename T>
+ friend auto get_buffer(appender out) -> detail::buffer<char>& {
+ return detail::get_container(out);
+ }
+
+ public:
+ using std::back_insert_iterator<detail::buffer<char>>::back_insert_iterator;
+ appender(base it) FMT_NOEXCEPT : base(it) {}
+ using _Unchecked_type = appender; // Mark iterator as checked.
+
+ auto operator++() FMT_NOEXCEPT -> appender& { return *this; }
+
+ auto operator++(int) FMT_NOEXCEPT -> appender { return *this; }
+};
+
+// A formatting argument. It is a trivially copyable/constructible type to
+// allow storage in basic_memory_buffer.
+template <typename Context> class basic_format_arg {
+ private:
+ detail::value<Context> value_;
+ detail::type type_;
+
+ template <typename ContextType, typename T>
+ friend FMT_CONSTEXPR auto detail::make_arg(const T& value)
+ -> basic_format_arg<ContextType>;
+
+ template <typename Visitor, typename Ctx>
+ friend FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis,
+ const basic_format_arg<Ctx>& arg)
+ -> decltype(vis(0));
+
+ friend class basic_format_args<Context>;
+ friend class dynamic_format_arg_store<Context>;
+
+ using char_type = typename Context::char_type;
+
+ template <typename T, typename Char, size_t NUM_ARGS, size_t NUM_NAMED_ARGS>
+ friend struct detail::arg_data;
+
+ basic_format_arg(const detail::named_arg_info<char_type>* args, size_t size)
+ : value_(args, size) {}
+
+ public:
+ class handle {
+ public:
+ explicit handle(detail::custom_value<Context> custom) : custom_(custom) {}
+
+ void format(typename Context::parse_context_type& parse_ctx,
+ Context& ctx) const {
+ custom_.format(custom_.value, parse_ctx, ctx);
+ }
+
+ private:
+ detail::custom_value<Context> custom_;
+ };
+
+ constexpr basic_format_arg() : type_(detail::type::none_type) {}
+
+ constexpr explicit operator bool() const FMT_NOEXCEPT {
+ return type_ != detail::type::none_type;
+ }
+
+ auto type() const -> detail::type { return type_; }
+
+ auto is_integral() const -> bool { return detail::is_integral_type(type_); }
+ auto is_arithmetic() const -> bool {
+ return detail::is_arithmetic_type(type_);
+ }
+};
+
+/**
+ \rst
+ Visits an argument dispatching to the appropriate visit method based on
+ the argument type. For example, if the argument type is ``double`` then
+ ``vis(value)`` will be called with the value of type ``double``.
+ \endrst
+ */
+template <typename Visitor, typename Context>
+FMT_CONSTEXPR FMT_INLINE auto visit_format_arg(
+ Visitor&& vis, const basic_format_arg<Context>& arg) -> decltype(vis(0)) {
+ switch (arg.type_) {
+ case detail::type::none_type:
+ break;
+ case detail::type::int_type:
+ return vis(arg.value_.int_value);
+ case detail::type::uint_type:
+ return vis(arg.value_.uint_value);
+ case detail::type::long_long_type:
+ return vis(arg.value_.long_long_value);
+ case detail::type::ulong_long_type:
+ return vis(arg.value_.ulong_long_value);
+ case detail::type::int128_type:
+ return vis(detail::convert_for_visit(arg.value_.int128_value));
+ case detail::type::uint128_type:
+ return vis(detail::convert_for_visit(arg.value_.uint128_value));
+ case detail::type::bool_type:
+ return vis(arg.value_.bool_value);
+ case detail::type::char_type:
+ return vis(arg.value_.char_value);
+ case detail::type::float_type:
+ return vis(arg.value_.float_value);
+ case detail::type::double_type:
+ return vis(arg.value_.double_value);
+ case detail::type::long_double_type:
+ return vis(arg.value_.long_double_value);
+ case detail::type::cstring_type:
+ return vis(arg.value_.string.data);
+ case detail::type::string_type:
+ using sv = basic_string_view<typename Context::char_type>;
+ return vis(sv(arg.value_.string.data, arg.value_.string.size));
+ case detail::type::pointer_type:
+ return vis(arg.value_.pointer);
+ case detail::type::custom_type:
+ return vis(typename basic_format_arg<Context>::handle(arg.value_.custom));
+ }
+ return vis(monostate());
+}
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+template <typename Char, typename InputIt>
+auto copy_str(InputIt begin, InputIt end, appender out) -> appender {
+ get_container(out).append(begin, end);
+ return out;
+}
+
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 500
+// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
+template <typename... Ts> struct void_t_impl { using type = void; };
+template <typename... Ts>
+using void_t = typename detail::void_t_impl<Ts...>::type;
+#else
+template <typename...> using void_t = void;
+#endif
+
+template <typename It, typename T, typename Enable = void>
+struct is_output_iterator : std::false_type {};
+
+template <typename It, typename T>
+struct is_output_iterator<
+ It, T,
+ void_t<typename std::iterator_traits<It>::iterator_category,
+ decltype(*std::declval<It>() = std::declval<T>())>>
+ : std::true_type {};
+
+template <typename OutputIt>
+struct is_back_insert_iterator : std::false_type {};
+template <typename Container>
+struct is_back_insert_iterator<std::back_insert_iterator<Container>>
+ : std::true_type {};
+
+template <typename OutputIt>
+struct is_contiguous_back_insert_iterator : std::false_type {};
+template <typename Container>
+struct is_contiguous_back_insert_iterator<std::back_insert_iterator<Container>>
+ : is_contiguous<Container> {};
+template <>
+struct is_contiguous_back_insert_iterator<appender> : std::true_type {};
+
+// A type-erased reference to an std::locale to avoid heavy <locale> include.
+class locale_ref {
+ private:
+ const void* locale_; // A type-erased pointer to std::locale.
+
+ public:
+ constexpr locale_ref() : locale_(nullptr) {}
+ template <typename Locale> explicit locale_ref(const Locale& loc);
+
+ explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; }
+
+ template <typename Locale> auto get() const -> Locale;
+};
+
+template <typename> constexpr auto encode_types() -> unsigned long long {
+ return 0;
+}
+
+template <typename Context, typename Arg, typename... Args>
+constexpr auto encode_types() -> unsigned long long {
+ return static_cast<unsigned>(mapped_type_constant<Arg, Context>::value) |
+ (encode_types<Context, Args...>() << packed_arg_bits);
+}
+
+template <typename Context, typename T>
+FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg<Context> {
+ basic_format_arg<Context> arg;
+ arg.type_ = mapped_type_constant<T, Context>::value;
+ arg.value_ = arg_mapper<Context>().map(value);
+ return arg;
+}
+
+// The type template parameter is there to avoid an ODR violation when using
+// a fallback formatter in one translation unit and an implicit conversion in
+// another (not recommended).
+template <bool IS_PACKED, typename Context, type, typename T,
+ FMT_ENABLE_IF(IS_PACKED)>
+FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value<Context> {
+ const auto& arg = arg_mapper<Context>().map(std::forward<T>(val));
+
+ constexpr bool formattable_char =
+ !std::is_same<decltype(arg), const unformattable_char&>::value;
+ static_assert(formattable_char, "Mixing character types is disallowed.");
+
+ constexpr bool formattable_const =
+ !std::is_same<decltype(arg), const unformattable_const&>::value;
+ static_assert(formattable_const, "Cannot format a const argument.");
+
+ // Formatting of arbitrary pointers is disallowed. If you want to output
+ // a pointer cast it to "void *" or "const void *". In particular, this
+ // forbids formatting of "[const] volatile char *" which is printed as bool
+ // by iostreams.
+ constexpr bool formattable_pointer =
+ !std::is_same<decltype(arg), const unformattable_pointer&>::value;
+ static_assert(formattable_pointer,
+ "Formatting of non-void pointers is disallowed.");
+
+ constexpr bool formattable =
+ !std::is_same<decltype(arg), const unformattable&>::value;
+ static_assert(
+ formattable,
+ "Cannot format an argument. To make type T formattable provide a "
+ "formatter<T> specialization: https://fmt.dev/latest/api.html#udt");
+ return {arg};
+}
+
+template <bool IS_PACKED, typename Context, type, typename T,
+ FMT_ENABLE_IF(!IS_PACKED)>
+inline auto make_arg(const T& value) -> basic_format_arg<Context> {
+ return make_arg<Context>(value);
+}
+FMT_END_DETAIL_NAMESPACE
+
+// Formatting context.
+template <typename OutputIt, typename Char> class basic_format_context {
+ public:
+ /** The character type for the output. */
+ using char_type = Char;
+
+ private:
+ OutputIt out_;
+ basic_format_args<basic_format_context> args_;
+ detail::locale_ref loc_;
+
+ public:
+ using iterator = OutputIt;
+ using format_arg = basic_format_arg<basic_format_context>;
+ using parse_context_type = basic_format_parse_context<Char>;
+ template <typename T> using formatter_type = formatter<T, char_type>;
+
+ basic_format_context(basic_format_context&&) = default;
+ basic_format_context(const basic_format_context&) = delete;
+ void operator=(const basic_format_context&) = delete;
+ /**
+ Constructs a ``basic_format_context`` object. References to the arguments are
+ stored in the object so make sure they have appropriate lifetimes.
+ */
+ constexpr basic_format_context(
+ OutputIt out, basic_format_args<basic_format_context> ctx_args,
+ detail::locale_ref loc = detail::locale_ref())
+ : out_(out), args_(ctx_args), loc_(loc) {}
+
+ constexpr auto arg(int id) const -> format_arg { return args_.get(id); }
+ FMT_CONSTEXPR auto arg(basic_string_view<char_type> name) -> format_arg {
+ return args_.get(name);
+ }
+ FMT_CONSTEXPR auto arg_id(basic_string_view<char_type> name) -> int {
+ return args_.get_id(name);
+ }
+ auto args() const -> const basic_format_args<basic_format_context>& {
+ return args_;
+ }
+
+ FMT_CONSTEXPR auto error_handler() -> detail::error_handler { return {}; }
+ void on_error(const char* message) { error_handler().on_error(message); }
+
+ // Returns an iterator to the beginning of the output range.
+ FMT_CONSTEXPR auto out() -> iterator { return out_; }
+
+ // Advances the begin iterator to ``it``.
+ void advance_to(iterator it) {
+ if (!detail::is_back_insert_iterator<iterator>()) out_ = it;
+ }
+
+ FMT_CONSTEXPR auto locale() -> detail::locale_ref { return loc_; }
+};
+
+template <typename Char>
+using buffer_context =
+ basic_format_context<detail::buffer_appender<Char>, Char>;
+using format_context = buffer_context<char>;
+
+// Workaround an alias issue: https://stackoverflow.com/q/62767544/471164.
+#define FMT_BUFFER_CONTEXT(Char) \
+ basic_format_context<detail::buffer_appender<Char>, Char>
+
+template <typename T, typename Char = char>
+using is_formattable = bool_constant<
+ !std::is_base_of<detail::unformattable,
+ decltype(detail::arg_mapper<buffer_context<Char>>().map(
+ std::declval<T>()))>::value &&
+ !detail::has_fallback_formatter<T, Char>::value>;
+
+/**
+ \rst
+ An array of references to arguments. It can be implicitly converted into
+ `~fmt::basic_format_args` for passing into type-erased formatting functions
+ such as `~fmt::vformat`.
+ \endrst
+ */
+template <typename Context, typename... Args>
+class format_arg_store
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
+ // Workaround a GCC template argument substitution bug.
+ : public basic_format_args<Context>
+#endif
+{
+ private:
+ static const size_t num_args = sizeof...(Args);
+ static const size_t num_named_args = detail::count_named_args<Args...>();
+ static const bool is_packed = num_args <= detail::max_packed_args;
+
+ using value_type = conditional_t<is_packed, detail::value<Context>,
+ basic_format_arg<Context>>;
+
+ detail::arg_data<value_type, typename Context::char_type, num_args,
+ num_named_args>
+ data_;
+
+ friend class basic_format_args<Context>;
+
+ static constexpr unsigned long long desc =
+ (is_packed ? detail::encode_types<Context, Args...>()
+ : detail::is_unpacked_bit | num_args) |
+ (num_named_args != 0
+ ? static_cast<unsigned long long>(detail::has_named_args_bit)
+ : 0);
+
+ public:
+ template <typename... T>
+ FMT_CONSTEXPR FMT_INLINE format_arg_store(T&&... args)
+ :
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
+ basic_format_args<Context>(*this),
+#endif
+ data_{detail::make_arg<
+ is_packed, Context,
+ detail::mapped_type_constant<remove_cvref_t<T>, Context>::value>(
+ std::forward<T>(args))...} {
+ detail::init_named_args(data_.named_args(), 0, 0, args...);
+ }
+};
+
+/**
+ \rst
+ Constructs a `~fmt::format_arg_store` object that contains references to
+ arguments and can be implicitly converted to `~fmt::format_args`. `Context`
+ can be omitted in which case it defaults to `~fmt::context`.
+ See `~fmt::arg` for lifetime considerations.
+ \endrst
+ */
+template <typename Context = format_context, typename... Args>
+constexpr auto make_format_args(Args&&... args)
+ -> format_arg_store<Context, remove_cvref_t<Args>...> {
+ return {std::forward<Args>(args)...};
+}
+
+/**
+ \rst
+ Returns a named argument to be used in a formatting function.
+ It should only be used in a call to a formatting function or
+ `dynamic_format_arg_store::push_back`.
+
+ **Example**::
+
+ fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23));
+ \endrst
+ */
+template <typename Char, typename T>
+inline auto arg(const Char* name, const T& arg) -> detail::named_arg<Char, T> {
+ static_assert(!detail::is_named_arg<T>(), "nested named arguments");
+ return {name, arg};
+}
+
+/**
+ \rst
+ A view of a collection of formatting arguments. To avoid lifetime issues it
+ should only be used as a parameter type in type-erased functions such as
+ ``vformat``::
+
+ void vlog(string_view format_str, format_args args); // OK
+ format_args args = make_format_args(42); // Error: dangling reference
+ \endrst
+ */
+template <typename Context> class basic_format_args {
+ public:
+ using size_type = int;
+ using format_arg = basic_format_arg<Context>;
+
+ private:
+ // A descriptor that contains information about formatting arguments.
+ // If the number of arguments is less or equal to max_packed_args then
+ // argument types are passed in the descriptor. This reduces binary code size
+ // per formatting function call.
+ unsigned long long desc_;
+ union {
+ // If is_packed() returns true then argument values are stored in values_;
+ // otherwise they are stored in args_. This is done to improve cache
+ // locality and reduce compiled code size since storing larger objects
+ // may require more code (at least on x86-64) even if the same amount of
+ // data is actually copied to stack. It saves ~10% on the bloat test.
+ const detail::value<Context>* values_;
+ const format_arg* args_;
+ };
+
+ constexpr auto is_packed() const -> bool {
+ return (desc_ & detail::is_unpacked_bit) == 0;
+ }
+ auto has_named_args() const -> bool {
+ return (desc_ & detail::has_named_args_bit) != 0;
+ }
+
+ FMT_CONSTEXPR auto type(int index) const -> detail::type {
+ int shift = index * detail::packed_arg_bits;
+ unsigned int mask = (1 << detail::packed_arg_bits) - 1;
+ return static_cast<detail::type>((desc_ >> shift) & mask);
+ }
+
+ constexpr FMT_INLINE basic_format_args(unsigned long long desc,
+ const detail::value<Context>* values)
+ : desc_(desc), values_(values) {}
+ constexpr basic_format_args(unsigned long long desc, const format_arg* args)
+ : desc_(desc), args_(args) {}
+
+ public:
+ constexpr basic_format_args() : desc_(0), args_(nullptr) {}
+
+ /**
+ \rst
+ Constructs a `basic_format_args` object from `~fmt::format_arg_store`.
+ \endrst
+ */
+ template <typename... Args>
+ constexpr FMT_INLINE basic_format_args(
+ const format_arg_store<Context, Args...>& store)
+ : basic_format_args(format_arg_store<Context, Args...>::desc,
+ store.data_.args()) {}
+
+ /**
+ \rst
+ Constructs a `basic_format_args` object from
+ `~fmt::dynamic_format_arg_store`.
+ \endrst
+ */
+ constexpr FMT_INLINE basic_format_args(
+ const dynamic_format_arg_store<Context>& store)
+ : basic_format_args(store.get_types(), store.data()) {}
+
+ /**
+ \rst
+ Constructs a `basic_format_args` object from a dynamic set of arguments.
+ \endrst
+ */
+ constexpr basic_format_args(const format_arg* args, int count)
+ : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count),
+ args) {}
+
+ /** Returns the argument with the specified id. */
+ FMT_CONSTEXPR auto get(int id) const -> format_arg {
+ format_arg arg;
+ if (!is_packed()) {
+ if (id < max_size()) arg = args_[id];
+ return arg;
+ }
+ if (id >= detail::max_packed_args) return arg;
+ arg.type_ = type(id);
+ if (arg.type_ == detail::type::none_type) return arg;
+ arg.value_ = values_[id];
+ return arg;
+ }
+
+ template <typename Char>
+ auto get(basic_string_view<Char> name) const -> format_arg {
+ int id = get_id(name);
+ return id >= 0 ? get(id) : format_arg();
+ }
+
+ template <typename Char>
+ auto get_id(basic_string_view<Char> name) const -> int {
+ if (!has_named_args()) return -1;
+ const auto& named_args =
+ (is_packed() ? values_[-1] : args_[-1].value_).named_args;
+ for (size_t i = 0; i < named_args.size; ++i) {
+ if (named_args.data[i].name == name) return named_args.data[i].id;
+ }
+ return -1;
+ }
+
+ auto max_size() const -> int {
+ unsigned long long max_packed = detail::max_packed_args;
+ return static_cast<int>(is_packed() ? max_packed
+ : desc_ & ~detail::is_unpacked_bit);
+ }
+};
+
+/** An alias to ``basic_format_args<format_context>``. */
+// A separate type would result in shorter symbols but break ABI compatibility
+// between clang and gcc on ARM (#1919).
+using format_args = basic_format_args<format_context>;
+
+// We cannot use enum classes as bit fields because of a gcc bug
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
+namespace align {
+enum type { none, left, right, center, numeric };
+}
+using align_t = align::type;
+namespace sign {
+enum type { none, minus, plus, space };
+}
+using sign_t = sign::type;
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+// Workaround an array initialization issue in gcc 4.8.
+template <typename Char> struct fill_t {
+ private:
+ enum { max_size = 4 };
+ Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)};
+ unsigned char size_ = 1;
+
+ public:
+ FMT_CONSTEXPR void operator=(basic_string_view<Char> s) {
+ auto size = s.size();
+ if (size > max_size) return throw_format_error("invalid fill");
+ for (size_t i = 0; i < size; ++i) data_[i] = s[i];
+ size_ = static_cast<unsigned char>(size);
+ }
+
+ constexpr auto size() const -> size_t { return size_; }
+ constexpr auto data() const -> const Char* { return data_; }
+
+ FMT_CONSTEXPR auto operator[](size_t index) -> Char& { return data_[index]; }
+ FMT_CONSTEXPR auto operator[](size_t index) const -> const Char& {
+ return data_[index];
+ }
+};
+FMT_END_DETAIL_NAMESPACE
+
+enum class presentation_type : unsigned char {
+ none,
+ // Integer types should go first,
+ dec, // 'd'
+ oct, // 'o'
+ hex_lower, // 'x'
+ hex_upper, // 'X'
+ bin_lower, // 'b'
+ bin_upper, // 'B'
+ hexfloat_lower, // 'a'
+ hexfloat_upper, // 'A'
+ exp_lower, // 'e'
+ exp_upper, // 'E'
+ fixed_lower, // 'f'
+ fixed_upper, // 'F'
+ general_lower, // 'g'
+ general_upper, // 'G'
+ chr, // 'c'
+ string, // 's'
+ pointer // 'p'
+};
+
+// Format specifiers for built-in and string types.
+template <typename Char> struct basic_format_specs {
+ int width;
+ int precision;
+ presentation_type type;
+ align_t align : 4;
+ sign_t sign : 3;
+ bool alt : 1; // Alternate form ('#').
+ bool localized : 1;
+ detail::fill_t<Char> fill;
+
+ constexpr basic_format_specs()
+ : width(0),
+ precision(-1),
+ type(presentation_type::none),
+ align(align::none),
+ sign(sign::none),
+ alt(false),
+ localized(false) {}
+};
+
+using format_specs = basic_format_specs<char>;
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+enum class arg_id_kind { none, index, name };
+
+// An argument reference.
+template <typename Char> struct arg_ref {
+ FMT_CONSTEXPR arg_ref() : kind(arg_id_kind::none), val() {}
+
+ FMT_CONSTEXPR explicit arg_ref(int index)
+ : kind(arg_id_kind::index), val(index) {}
+ FMT_CONSTEXPR explicit arg_ref(basic_string_view<Char> name)
+ : kind(arg_id_kind::name), val(name) {}
+
+ FMT_CONSTEXPR auto operator=(int idx) -> arg_ref& {
+ kind = arg_id_kind::index;
+ val.index = idx;
+ return *this;
+ }
+
+ arg_id_kind kind;
+ union value {
+ FMT_CONSTEXPR value(int id = 0) : index{id} {}
+ FMT_CONSTEXPR value(basic_string_view<Char> n) : name(n) {}
+
+ int index;
+ basic_string_view<Char> name;
+ } val;
+};
+
+// Format specifiers with width and precision resolved at formatting rather
+// than parsing time to allow re-using the same parsed specifiers with
+// different sets of arguments (precompilation of format strings).
+template <typename Char>
+struct dynamic_format_specs : basic_format_specs<Char> {
+ arg_ref<Char> width_ref;
+ arg_ref<Char> precision_ref;
+};
+
+struct auto_id {};
+
+// A format specifier handler that sets fields in basic_format_specs.
+template <typename Char> class specs_setter {
+ protected:
+ basic_format_specs<Char>& specs_;
+
+ public:
+ explicit FMT_CONSTEXPR specs_setter(basic_format_specs<Char>& specs)
+ : specs_(specs) {}
+
+ FMT_CONSTEXPR specs_setter(const specs_setter& other)
+ : specs_(other.specs_) {}
+
+ FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; }
+ FMT_CONSTEXPR void on_fill(basic_string_view<Char> fill) {
+ specs_.fill = fill;
+ }
+ FMT_CONSTEXPR void on_sign(sign_t s) { specs_.sign = s; }
+ FMT_CONSTEXPR void on_hash() { specs_.alt = true; }
+ FMT_CONSTEXPR void on_localized() { specs_.localized = true; }
+
+ FMT_CONSTEXPR void on_zero() {
+ if (specs_.align == align::none) specs_.align = align::numeric;
+ specs_.fill[0] = Char('0');
+ }
+
+ FMT_CONSTEXPR void on_width(int width) { specs_.width = width; }
+ FMT_CONSTEXPR void on_precision(int precision) {
+ specs_.precision = precision;
+ }
+ FMT_CONSTEXPR void end_precision() {}
+
+ FMT_CONSTEXPR void on_type(presentation_type type) { specs_.type = type; }
+};
+
+// Format spec handler that saves references to arguments representing dynamic
+// width and precision to be resolved at formatting time.
+template <typename ParseContext>
+class dynamic_specs_handler
+ : public specs_setter<typename ParseContext::char_type> {
+ public:
+ using char_type = typename ParseContext::char_type;
+
+ FMT_CONSTEXPR dynamic_specs_handler(dynamic_format_specs<char_type>& specs,
+ ParseContext& ctx)
+ : specs_setter<char_type>(specs), specs_(specs), context_(ctx) {}
+
+ FMT_CONSTEXPR dynamic_specs_handler(const dynamic_specs_handler& other)
+ : specs_setter<char_type>(other),
+ specs_(other.specs_),
+ context_(other.context_) {}
+
+ template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
+ specs_.width_ref = make_arg_ref(arg_id);
+ }
+
+ template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
+ specs_.precision_ref = make_arg_ref(arg_id);
+ }
+
+ FMT_CONSTEXPR void on_error(const char* message) {
+ context_.on_error(message);
+ }
+
+ private:
+ dynamic_format_specs<char_type>& specs_;
+ ParseContext& context_;
+
+ using arg_ref_type = arg_ref<char_type>;
+
+ FMT_CONSTEXPR auto make_arg_ref(int arg_id) -> arg_ref_type {
+ context_.check_arg_id(arg_id);
+ return arg_ref_type(arg_id);
+ }
+
+ FMT_CONSTEXPR auto make_arg_ref(auto_id) -> arg_ref_type {
+ return arg_ref_type(context_.next_arg_id());
+ }
+
+ FMT_CONSTEXPR auto make_arg_ref(basic_string_view<char_type> arg_id)
+ -> arg_ref_type {
+ context_.check_arg_id(arg_id);
+ basic_string_view<char_type> format_str(
+ context_.begin(), to_unsigned(context_.end() - context_.begin()));
+ return arg_ref_type(arg_id);
+ }
+};
+
+template <typename Char> constexpr bool is_ascii_letter(Char c) {
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+
+// Converts a character to ASCII. Returns a number > 127 on conversion failure.
+template <typename Char, FMT_ENABLE_IF(std::is_integral<Char>::value)>
+constexpr auto to_ascii(Char value) -> Char {
+ return value;
+}
+template <typename Char, FMT_ENABLE_IF(std::is_enum<Char>::value)>
+constexpr auto to_ascii(Char value) ->
+ typename std::underlying_type<Char>::type {
+ return value;
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int {
+ if (const_check(sizeof(Char) != 1)) return 1;
+ auto lengths =
+ "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4";
+ int len = lengths[static_cast<unsigned char>(*begin) >> 3];
+
+ // Compute the pointer to the next character early so that the next
+ // iteration can start working on the next character. Neither Clang
+ // nor GCC figure out this reordering on their own.
+ return len + !len;
+}
+
+// Return the result via the out param to workaround gcc bug 77539.
+template <bool IS_CONSTEXPR, typename T, typename Ptr = const T*>
+FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr& out) -> bool {
+ for (out = first; out != last; ++out) {
+ if (*out == value) return true;
+ }
+ return false;
+}
+
+template <>
+inline auto find<false, char>(const char* first, const char* last, char value,
+ const char*& out) -> bool {
+ out = static_cast<const char*>(
+ std::memchr(first, value, to_unsigned(last - first)));
+ return out != nullptr;
+}
+
+// Parses the range [begin, end) as an unsigned integer. This function assumes
+// that the range is non-empty and the first character is a digit.
+template <typename Char>
+FMT_CONSTEXPR auto parse_nonnegative_int(const Char*& begin, const Char* end,
+ int error_value) noexcept -> int {
+ FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', "");
+ unsigned value = 0, prev = 0;
+ auto p = begin;
+ do {
+ prev = value;
+ value = value * 10 + unsigned(*p - '0');
+ ++p;
+ } while (p != end && '0' <= *p && *p <= '9');
+ auto num_digits = p - begin;
+ begin = p;
+ if (num_digits <= std::numeric_limits<int>::digits10)
+ return static_cast<int>(value);
+ // Check for overflow.
+ const unsigned max = to_unsigned((std::numeric_limits<int>::max)());
+ return num_digits == std::numeric_limits<int>::digits10 + 1 &&
+ prev * 10ull + unsigned(p[-1] - '0') <= max
+ ? static_cast<int>(value)
+ : error_value;
+}
+
+// Parses fill and alignment.
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end,
+ Handler&& handler) -> const Char* {
+ FMT_ASSERT(begin != end, "");
+ auto align = align::none;
+ auto p = begin + code_point_length(begin);
+ if (p >= end) p = begin;
+ for (;;) {
+ switch (to_ascii(*p)) {
+ case '<':
+ align = align::left;
+ break;
+ case '>':
+ align = align::right;
+ break;
+ case '^':
+ align = align::center;
+ break;
+ default:
+ break;
+ }
+ if (align != align::none) {
+ if (p != begin) {
+ auto c = *begin;
+ if (c == '{')
+ return handler.on_error("invalid fill character '{'"), begin;
+ handler.on_fill(basic_string_view<Char>(begin, to_unsigned(p - begin)));
+ begin = p + 1;
+ } else
+ ++begin;
+ handler.on_align(align);
+ break;
+ } else if (p == begin) {
+ break;
+ }
+ p = begin;
+ }
+ return begin;
+}
+
+template <typename Char> FMT_CONSTEXPR bool is_name_start(Char c) {
+ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || '_' == c;
+}
+
+template <typename Char, typename IDHandler>
+FMT_CONSTEXPR auto do_parse_arg_id(const Char* begin, const Char* end,
+ IDHandler&& handler) -> const Char* {
+ FMT_ASSERT(begin != end, "");
+ Char c = *begin;
+ if (c >= '0' && c <= '9') {
+ int index = 0;
+ if (c != '0')
+ index =
+ parse_nonnegative_int(begin, end, (std::numeric_limits<int>::max)());
+ else
+ ++begin;
+ if (begin == end || (*begin != '}' && *begin != ':'))
+ handler.on_error("invalid format string");
+ else
+ handler(index);
+ return begin;
+ }
+ if (!is_name_start(c)) {
+ handler.on_error("invalid format string");
+ return begin;
+ }
+ auto it = begin;
+ do {
+ ++it;
+ } while (it != end && (is_name_start(c = *it) || ('0' <= c && c <= '9')));
+ handler(basic_string_view<Char>(begin, to_unsigned(it - begin)));
+ return it;
+}
+
+template <typename Char, typename IDHandler>
+FMT_CONSTEXPR FMT_INLINE auto parse_arg_id(const Char* begin, const Char* end,
+ IDHandler&& handler) -> const Char* {
+ Char c = *begin;
+ if (c != '}' && c != ':') return do_parse_arg_id(begin, end, handler);
+ handler();
+ return begin;
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_width(const Char* begin, const Char* end,
+ Handler&& handler) -> const Char* {
+ using detail::auto_id;
+ struct width_adapter {
+ Handler& handler;
+
+ FMT_CONSTEXPR void operator()() { handler.on_dynamic_width(auto_id()); }
+ FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_width(id); }
+ FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
+ handler.on_dynamic_width(id);
+ }
+ FMT_CONSTEXPR void on_error(const char* message) {
+ if (message) handler.on_error(message);
+ }
+ };
+
+ FMT_ASSERT(begin != end, "");
+ if ('0' <= *begin && *begin <= '9') {
+ int width = parse_nonnegative_int(begin, end, -1);
+ if (width != -1)
+ handler.on_width(width);
+ else
+ handler.on_error("number is too big");
+ } else if (*begin == '{') {
+ ++begin;
+ if (begin != end) begin = parse_arg_id(begin, end, width_adapter{handler});
+ if (begin == end || *begin != '}')
+ return handler.on_error("invalid format string"), begin;
+ ++begin;
+ }
+ return begin;
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end,
+ Handler&& handler) -> const Char* {
+ using detail::auto_id;
+ struct precision_adapter {
+ Handler& handler;
+
+ FMT_CONSTEXPR void operator()() { handler.on_dynamic_precision(auto_id()); }
+ FMT_CONSTEXPR void operator()(int id) { handler.on_dynamic_precision(id); }
+ FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
+ handler.on_dynamic_precision(id);
+ }
+ FMT_CONSTEXPR void on_error(const char* message) {
+ if (message) handler.on_error(message);
+ }
+ };
+
+ ++begin;
+ auto c = begin != end ? *begin : Char();
+ if ('0' <= c && c <= '9') {
+ auto precision = parse_nonnegative_int(begin, end, -1);
+ if (precision != -1)
+ handler.on_precision(precision);
+ else
+ handler.on_error("number is too big");
+ } else if (c == '{') {
+ ++begin;
+ if (begin != end)
+ begin = parse_arg_id(begin, end, precision_adapter{handler});
+ if (begin == end || *begin++ != '}')
+ return handler.on_error("invalid format string"), begin;
+ } else {
+ return handler.on_error("missing precision specifier"), begin;
+ }
+ handler.end_precision();
+ return begin;
+}
+
+template <typename Char>
+FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type {
+ switch (to_ascii(type)) {
+ case 'd':
+ return presentation_type::dec;
+ case 'o':
+ return presentation_type::oct;
+ case 'x':
+ return presentation_type::hex_lower;
+ case 'X':
+ return presentation_type::hex_upper;
+ case 'b':
+ return presentation_type::bin_lower;
+ case 'B':
+ return presentation_type::bin_upper;
+ case 'a':
+ return presentation_type::hexfloat_lower;
+ case 'A':
+ return presentation_type::hexfloat_upper;
+ case 'e':
+ return presentation_type::exp_lower;
+ case 'E':
+ return presentation_type::exp_upper;
+ case 'f':
+ return presentation_type::fixed_lower;
+ case 'F':
+ return presentation_type::fixed_upper;
+ case 'g':
+ return presentation_type::general_lower;
+ case 'G':
+ return presentation_type::general_upper;
+ case 'c':
+ return presentation_type::chr;
+ case 's':
+ return presentation_type::string;
+ case 'p':
+ return presentation_type::pointer;
+ default:
+ return presentation_type::none;
+ }
+}
+
+// Parses standard format specifiers and sends notifications about parsed
+// components to handler.
+template <typename Char, typename SpecHandler>
+FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin,
+ const Char* end,
+ SpecHandler&& handler)
+ -> const Char* {
+ if (1 < end - begin && begin[1] == '}' && is_ascii_letter(*begin) &&
+ *begin != 'L') {
+ presentation_type type = parse_presentation_type(*begin++);
+ if (type == presentation_type::none)
+ handler.on_error("invalid type specifier");
+ handler.on_type(type);
+ return begin;
+ }
+
+ if (begin == end) return begin;
+
+ begin = parse_align(begin, end, handler);
+ if (begin == end) return begin;
+
+ // Parse sign.
+ switch (to_ascii(*begin)) {
+ case '+':
+ handler.on_sign(sign::plus);
+ ++begin;
+ break;
+ case '-':
+ handler.on_sign(sign::minus);
+ ++begin;
+ break;
+ case ' ':
+ handler.on_sign(sign::space);
+ ++begin;
+ break;
+ default:
+ break;
+ }
+ if (begin == end) return begin;
+
+ if (*begin == '#') {
+ handler.on_hash();
+ if (++begin == end) return begin;
+ }
+
+ // Parse zero flag.
+ if (*begin == '0') {
+ handler.on_zero();
+ if (++begin == end) return begin;
+ }
+
+ begin = parse_width(begin, end, handler);
+ if (begin == end) return begin;
+
+ // Parse precision.
+ if (*begin == '.') {
+ begin = parse_precision(begin, end, handler);
+ if (begin == end) return begin;
+ }
+
+ if (*begin == 'L') {
+ handler.on_localized();
+ ++begin;
+ }
+
+ // Parse type.
+ if (begin != end && *begin != '}') {
+ presentation_type type = parse_presentation_type(*begin++);
+ if (type == presentation_type::none)
+ handler.on_error("invalid type specifier");
+ handler.on_type(type);
+ }
+ return begin;
+}
+
+template <typename Char, typename Handler>
+FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end,
+ Handler&& handler) -> const Char* {
+ struct id_adapter {
+ Handler& handler;
+ int arg_id;
+
+ FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); }
+ FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); }
+ FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
+ arg_id = handler.on_arg_id(id);
+ }
+ FMT_CONSTEXPR void on_error(const char* message) {
+ if (message) handler.on_error(message);
+ }
+ };
+
+ ++begin;
+ if (begin == end) return handler.on_error("invalid format string"), end;
+ if (*begin == '}') {
+ handler.on_replacement_field(handler.on_arg_id(), begin);
+ } else if (*begin == '{') {
+ handler.on_text(begin, begin + 1);
+ } else {
+ auto adapter = id_adapter{handler, 0};
+ begin = parse_arg_id(begin, end, adapter);
+ Char c = begin != end ? *begin : Char();
+ if (c == '}') {
+ handler.on_replacement_field(adapter.arg_id, begin);
+ } else if (c == ':') {
+ begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
+ if (begin == end || *begin != '}')
+ return handler.on_error("unknown format specifier"), end;
+ } else {
+ return handler.on_error("missing '}' in format string"), end;
+ }
+ }
+ return begin + 1;
+}
+
+template <bool IS_CONSTEXPR, typename Char, typename Handler>
+FMT_CONSTEXPR FMT_INLINE void parse_format_string(
+ basic_string_view<Char> format_str, Handler&& handler) {
+ // Workaround a name-lookup bug in MSVC's modules implementation.
+ using detail::find;
+
+ auto begin = format_str.data();
+ auto end = begin + format_str.size();
+ if (end - begin < 32) {
+ // Use a simple loop instead of memchr for small strings.
+ const Char* p = begin;
+ while (p != end) {
+ auto c = *p++;
+ if (c == '{') {
+ handler.on_text(begin, p - 1);
+ begin = p = parse_replacement_field(p - 1, end, handler);
+ } else if (c == '}') {
+ if (p == end || *p != '}')
+ return handler.on_error("unmatched '}' in format string");
+ handler.on_text(begin, p);
+ begin = ++p;
+ }
+ }
+ handler.on_text(begin, end);
+ return;
+ }
+ struct writer {
+ FMT_CONSTEXPR void operator()(const Char* pbegin, const Char* pend) {
+ if (pbegin == pend) return;
+ for (;;) {
+ const Char* p = nullptr;
+ if (!find<IS_CONSTEXPR>(pbegin, pend, Char('}'), p))
+ return handler_.on_text(pbegin, pend);
+ ++p;
+ if (p == pend || *p != '}')
+ return handler_.on_error("unmatched '}' in format string");
+ handler_.on_text(pbegin, p);
+ pbegin = p + 1;
+ }
+ }
+ Handler& handler_;
+ } write{handler};
+ while (begin != end) {
+ // Doing two passes with memchr (one for '{' and another for '}') is up to
+ // 2.5x faster than the naive one-pass implementation on big format strings.
+ const Char* p = begin;
+ if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, Char('{'), p))
+ return write(begin, end);
+ write(begin, p);
+ begin = parse_replacement_field(p, end, handler);
+ }
+}
+
+template <typename T, typename ParseContext>
+FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx)
+ -> decltype(ctx.begin()) {
+ using char_type = typename ParseContext::char_type;
+ using context = buffer_context<char_type>;
+ using mapped_type = conditional_t<
+ mapped_type_constant<T, context>::value != type::custom_type,
+ decltype(arg_mapper<context>().map(std::declval<const T&>())), T>;
+ auto f = conditional_t<has_formatter<mapped_type, context>::value,
+ formatter<mapped_type, char_type>,
+ fallback_formatter<T, char_type>>();
+ return f.parse(ctx);
+}
+
+// A parse context with extra argument id checks. It is only used at compile
+// time because adding checks at runtime would introduce substantial overhead
+// and would be redundant since argument ids are checked when arguments are
+// retrieved anyway.
+template <typename Char, typename ErrorHandler = error_handler>
+class compile_parse_context
+ : public basic_format_parse_context<Char, ErrorHandler> {
+ private:
+ int num_args_;
+ using base = basic_format_parse_context<Char, ErrorHandler>;
+
+ public:
+ explicit FMT_CONSTEXPR compile_parse_context(
+ basic_string_view<Char> format_str,
+ int num_args = (std::numeric_limits<int>::max)(), ErrorHandler eh = {})
+ : base(format_str, eh), num_args_(num_args) {}
+
+ FMT_CONSTEXPR auto next_arg_id() -> int {
+ int id = base::next_arg_id();
+ if (id >= num_args_) this->on_error("argument not found");
+ return id;
+ }
+
+ FMT_CONSTEXPR void check_arg_id(int id) {
+ base::check_arg_id(id);
+ if (id >= num_args_) this->on_error("argument not found");
+ }
+ using base::check_arg_id;
+};
+
+template <typename ErrorHandler>
+FMT_CONSTEXPR void check_int_type_spec(presentation_type type,
+ ErrorHandler&& eh) {
+ if (type > presentation_type::bin_upper && type != presentation_type::chr)
+ eh.on_error("invalid type specifier");
+}
+
+// Checks char specs and returns true if the type spec is char (and not int).
+template <typename Char, typename ErrorHandler = error_handler>
+FMT_CONSTEXPR auto check_char_specs(const basic_format_specs<Char>& specs,
+ ErrorHandler&& eh = {}) -> bool {
+ if (specs.type != presentation_type::none &&
+ specs.type != presentation_type::chr) {
+ check_int_type_spec(specs.type, eh);
+ return false;
+ }
+ if (specs.align == align::numeric || specs.sign != sign::none || specs.alt)
+ eh.on_error("invalid format specifier for char");
+ return true;
+}
+
+// A floating-point presentation format.
+enum class float_format : unsigned char {
+ general, // General: exponent notation or fixed point based on magnitude.
+ exp, // Exponent notation with the default precision of 6, e.g. 1.2e-3.
+ fixed, // Fixed point with the default precision of 6, e.g. 0.0012.
+ hex
+};
+
+struct float_specs {
+ int precision;
+ float_format format : 8;
+ sign_t sign : 8;
+ bool upper : 1;
+ bool locale : 1;
+ bool binary32 : 1;
+ bool fallback : 1;
+ bool showpoint : 1;
+};
+
+template <typename ErrorHandler = error_handler, typename Char>
+FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs<Char>& specs,
+ ErrorHandler&& eh = {})
+ -> float_specs {
+ auto result = float_specs();
+ result.showpoint = specs.alt;
+ result.locale = specs.localized;
+ switch (specs.type) {
+ case presentation_type::none:
+ result.format = float_format::general;
+ break;
+ case presentation_type::general_upper:
+ result.upper = true;
+ FMT_FALLTHROUGH;
+ case presentation_type::general_lower:
+ result.format = float_format::general;
+ break;
+ case presentation_type::exp_upper:
+ result.upper = true;
+ FMT_FALLTHROUGH;
+ case presentation_type::exp_lower:
+ result.format = float_format::exp;
+ result.showpoint |= specs.precision != 0;
+ break;
+ case presentation_type::fixed_upper:
+ result.upper = true;
+ FMT_FALLTHROUGH;
+ case presentation_type::fixed_lower:
+ result.format = float_format::fixed;
+ result.showpoint |= specs.precision != 0;
+ break;
+ case presentation_type::hexfloat_upper:
+ result.upper = true;
+ FMT_FALLTHROUGH;
+ case presentation_type::hexfloat_lower:
+ result.format = float_format::hex;
+ break;
+ default:
+ eh.on_error("invalid type specifier");
+ break;
+ }
+ return result;
+}
+
+template <typename ErrorHandler = error_handler>
+FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type,
+ ErrorHandler&& eh = {}) -> bool {
+ if (type == presentation_type::none || type == presentation_type::string)
+ return true;
+ if (type != presentation_type::pointer) eh.on_error("invalid type specifier");
+ return false;
+}
+
+template <typename ErrorHandler = error_handler>
+FMT_CONSTEXPR void check_string_type_spec(presentation_type type,
+ ErrorHandler&& eh = {}) {
+ if (type != presentation_type::none && type != presentation_type::string)
+ eh.on_error("invalid type specifier");
+}
+
+template <typename ErrorHandler>
+FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type,
+ ErrorHandler&& eh) {
+ if (type != presentation_type::none && type != presentation_type::pointer)
+ eh.on_error("invalid type specifier");
+}
+
+// A parse_format_specs handler that checks if specifiers are consistent with
+// the argument type.
+template <typename Handler> class specs_checker : public Handler {
+ private:
+ detail::type arg_type_;
+
+ FMT_CONSTEXPR void require_numeric_argument() {
+ if (!is_arithmetic_type(arg_type_))
+ this->on_error("format specifier requires numeric argument");
+ }
+
+ public:
+ FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type)
+ : Handler(handler), arg_type_(arg_type) {}
+
+ FMT_CONSTEXPR void on_align(align_t align) {
+ if (align == align::numeric) require_numeric_argument();
+ Handler::on_align(align);
+ }
+
+ FMT_CONSTEXPR void on_sign(sign_t s) {
+ require_numeric_argument();
+ if (is_integral_type(arg_type_) && arg_type_ != type::int_type &&
+ arg_type_ != type::long_long_type && arg_type_ != type::char_type) {
+ this->on_error("format specifier requires signed argument");
+ }
+ Handler::on_sign(s);
+ }
+
+ FMT_CONSTEXPR void on_hash() {
+ require_numeric_argument();
+ Handler::on_hash();
+ }
+
+ FMT_CONSTEXPR void on_localized() {
+ require_numeric_argument();
+ Handler::on_localized();
+ }
+
+ FMT_CONSTEXPR void on_zero() {
+ require_numeric_argument();
+ Handler::on_zero();
+ }
+
+ FMT_CONSTEXPR void end_precision() {
+ if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type)
+ this->on_error("precision not allowed for this argument type");
+ }
+};
+
+constexpr int invalid_arg_index = -1;
+
+#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+template <int N, typename T, typename... Args, typename Char>
+constexpr auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
+ if constexpr (detail::is_statically_named_arg<T>()) {
+ if (name == T::name) return N;
+ }
+ if constexpr (sizeof...(Args) > 0)
+ return get_arg_index_by_name<N + 1, Args...>(name);
+ (void)name; // Workaround an MSVC bug about "unused" parameter.
+ return invalid_arg_index;
+}
+#endif
+
+template <typename... Args, typename Char>
+FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view<Char> name) -> int {
+#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+ if constexpr (sizeof...(Args) > 0)
+ return get_arg_index_by_name<0, Args...>(name);
+#endif
+ (void)name;
+ return invalid_arg_index;
+}
+
+template <typename Char, typename ErrorHandler, typename... Args>
+class format_string_checker {
+ private:
+ using parse_context_type = compile_parse_context<Char, ErrorHandler>;
+ enum { num_args = sizeof...(Args) };
+
+ // Format specifier parsing function.
+ using parse_func = const Char* (*)(parse_context_type&);
+
+ parse_context_type context_;
+ parse_func parse_funcs_[num_args > 0 ? num_args : 1];
+
+ public:
+ explicit FMT_CONSTEXPR format_string_checker(
+ basic_string_view<Char> format_str, ErrorHandler eh)
+ : context_(format_str, num_args, eh),
+ parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
+
+ FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
+
+ FMT_CONSTEXPR auto on_arg_id() -> int { return context_.next_arg_id(); }
+ FMT_CONSTEXPR auto on_arg_id(int id) -> int {
+ return context_.check_arg_id(id), id;
+ }
+ FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
+#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+ auto index = get_arg_index_by_name<Args...>(id);
+ if (index == invalid_arg_index) on_error("named argument is not found");
+ return context_.check_arg_id(index), index;
+#else
+ (void)id;
+ on_error("compile-time checks for named arguments require C++20 support");
+ return 0;
+#endif
+ }
+
+ FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
+
+ FMT_CONSTEXPR auto on_format_specs(int id, const Char* begin, const Char*)
+ -> const Char* {
+ context_.advance_to(context_.begin() + (begin - &*context_.begin()));
+ // id >= 0 check is a workaround for gcc 10 bug (#2065).
+ return id >= 0 && id < num_args ? parse_funcs_[id](context_) : begin;
+ }
+
+ FMT_CONSTEXPR void on_error(const char* message) {
+ context_.on_error(message);
+ }
+};
+
+template <typename... Args, typename S,
+ enable_if_t<(is_compile_string<S>::value), int>>
+void check_format_string(S format_str) {
+ FMT_CONSTEXPR auto s = to_string_view(format_str);
+ using checker = format_string_checker<typename S::char_type, error_handler,
+ remove_cvref_t<Args>...>;
+ FMT_CONSTEXPR bool invalid_format =
+ (parse_format_string<true>(s, checker(s, {})), true);
+ ignore_unused(invalid_format);
+}
+
+template <typename Char>
+void vformat_to(
+ buffer<Char>& buf, basic_string_view<Char> fmt,
+ basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args,
+ locale_ref loc = {});
+
+FMT_API void vprint_mojibake(std::FILE*, string_view, format_args);
+#ifndef _WIN32
+inline void vprint_mojibake(std::FILE*, string_view, format_args) {}
+#endif
+FMT_END_DETAIL_NAMESPACE
+
+// A formatter specialization for the core types corresponding to detail::type
+// constants.
+template <typename T, typename Char>
+struct formatter<T, Char,
+ enable_if_t<detail::type_constant<T, Char>::value !=
+ detail::type::custom_type>> {
+ private:
+ detail::dynamic_format_specs<Char> specs_;
+
+ public:
+ // Parses format specifiers stopping either at the end of the range or at the
+ // terminating '}'.
+ template <typename ParseContext>
+ FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
+ auto begin = ctx.begin(), end = ctx.end();
+ if (begin == end) return begin;
+ using handler_type = detail::dynamic_specs_handler<ParseContext>;
+ auto type = detail::type_constant<T, Char>::value;
+ auto checker =
+ detail::specs_checker<handler_type>(handler_type(specs_, ctx), type);
+ auto it = detail::parse_format_specs(begin, end, checker);
+ auto eh = ctx.error_handler();
+ switch (type) {
+ case detail::type::none_type:
+ FMT_ASSERT(false, "invalid argument type");
+ break;
+ case detail::type::bool_type:
+ if (specs_.type == presentation_type::none ||
+ specs_.type == presentation_type::string) {
+ break;
+ }
+ FMT_FALLTHROUGH;
+ case detail::type::int_type:
+ case detail::type::uint_type:
+ case detail::type::long_long_type:
+ case detail::type::ulong_long_type:
+ case detail::type::int128_type:
+ case detail::type::uint128_type:
+ detail::check_int_type_spec(specs_.type, eh);
+ break;
+ case detail::type::char_type:
+ detail::check_char_specs(specs_, eh);
+ break;
+ case detail::type::float_type:
+ if (detail::const_check(FMT_USE_FLOAT))
+ detail::parse_float_type_spec(specs_, eh);
+ else
+ FMT_ASSERT(false, "float support disabled");
+ break;
+ case detail::type::double_type:
+ if (detail::const_check(FMT_USE_DOUBLE))
+ detail::parse_float_type_spec(specs_, eh);
+ else
+ FMT_ASSERT(false, "double support disabled");
+ break;
+ case detail::type::long_double_type:
+ if (detail::const_check(FMT_USE_LONG_DOUBLE))
+ detail::parse_float_type_spec(specs_, eh);
+ else
+ FMT_ASSERT(false, "long double support disabled");
+ break;
+ case detail::type::cstring_type:
+ detail::check_cstring_type_spec(specs_.type, eh);
+ break;
+ case detail::type::string_type:
+ detail::check_string_type_spec(specs_.type, eh);
+ break;
+ case detail::type::pointer_type:
+ detail::check_pointer_type_spec(specs_.type, eh);
+ break;
+ case detail::type::custom_type:
+ // Custom format specifiers are checked in parse functions of
+ // formatter specializations.
+ break;
+ }
+ return it;
+ }
+
+ template <typename FormatContext>
+ FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const
+ -> decltype(ctx.out());
+};
+
+template <typename Char> struct basic_runtime { basic_string_view<Char> str; };
+
+/** A compile-time format string. */
+template <typename Char, typename... Args> class basic_format_string {
+ private:
+ basic_string_view<Char> str_;
+
+ public:
+ template <typename S,
+ FMT_ENABLE_IF(
+ std::is_convertible<const S&, basic_string_view<Char>>::value)>
+ FMT_CONSTEVAL FMT_INLINE basic_format_string(const S& s) : str_(s) {
+ static_assert(
+ detail::count<
+ (std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
+ std::is_reference<Args>::value)...>() == 0,
+ "passing views as lvalues is disallowed");
+#ifdef FMT_HAS_CONSTEVAL
+ if constexpr (detail::count_named_args<Args...>() ==
+ detail::count_statically_named_args<Args...>()) {
+ using checker = detail::format_string_checker<Char, detail::error_handler,
+ remove_cvref_t<Args>...>;
+ detail::parse_format_string<true>(str_, checker(s, {}));
+ }
+#else
+ detail::check_format_string<Args...>(s);
+#endif
+ }
+ basic_format_string(basic_runtime<Char> r) : str_(r.str) {}
+
+ FMT_INLINE operator basic_string_view<Char>() const { return str_; }
+};
+
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
+// Workaround broken conversion on older gcc.
+template <typename... Args> using format_string = string_view;
+template <typename S> auto runtime(const S& s) -> basic_string_view<char_t<S>> {
+ return s;
+}
+#else
+template <typename... Args>
+using format_string = basic_format_string<char, type_identity_t<Args>...>;
+/**
+ \rst
+ Creates a runtime format string.
+
+ **Example**::
+
+ // Check format string at runtime instead of compile-time.
+ fmt::print(fmt::runtime("{:d}"), "I am not a number");
+ \endrst
+ */
+template <typename S> auto runtime(const S& s) -> basic_runtime<char_t<S>> {
+ return {{s}};
+}
+#endif
+
+FMT_API auto vformat(string_view fmt, format_args args) -> std::string;
+
+/**
+ \rst
+ Formats ``args`` according to specifications in ``fmt`` and returns the result
+ as a string.
+
+ **Example**::
+
+ #include <fmt/core.h>
+ std::string message = fmt::format("The answer is {}.", 42);
+ \endrst
+*/
+template <typename... T>
+FMT_NODISCARD FMT_INLINE auto format(format_string<T...> fmt, T&&... args)
+ -> std::string {
+ return vformat(fmt, fmt::make_format_args(args...));
+}
+
+/** Formats a string and writes the output to ``out``. */
+template <typename OutputIt,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt {
+ using detail::get_buffer;
+ auto&& buf = get_buffer<char>(out);
+ detail::vformat_to(buf, fmt, args, {});
+ return detail::get_iterator(buf);
+}
+
+/**
+ \rst
+ Formats ``args`` according to specifications in ``fmt``, writes the result to
+ the output iterator ``out`` and returns the iterator past the end of the output
+ range. `format_to` does not append a terminating null character.
+
+ **Example**::
+
+ auto out = std::vector<char>();
+ fmt::format_to(std::back_inserter(out), "{}", 42);
+ \endrst
+ */
+template <typename OutputIt, typename... T,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+FMT_INLINE auto format_to(OutputIt out, format_string<T...> fmt, T&&... args)
+ -> OutputIt {
+ return vformat_to(out, fmt, fmt::make_format_args(args...));
+}
+
+template <typename OutputIt> struct format_to_n_result {
+ /** Iterator past the end of the output range. */
+ OutputIt out;
+ /** Total (not truncated) output size. */
+ size_t size;
+};
+
+template <typename OutputIt, typename... T,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args)
+ -> format_to_n_result<OutputIt> {
+ using traits = detail::fixed_buffer_traits;
+ auto buf = detail::iterator_buffer<OutputIt, char, traits>(out, n);
+ detail::vformat_to(buf, fmt, args, {});
+ return {buf.out(), buf.count()};
+}
+
+/**
+ \rst
+ Formats ``args`` according to specifications in ``fmt``, writes up to ``n``
+ characters of the result to the output iterator ``out`` and returns the total
+ (not truncated) output size and the iterator past the end of the output range.
+ `format_to_n` does not append a terminating null character.
+ \endrst
+ */
+template <typename OutputIt, typename... T,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value)>
+FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string<T...> fmt,
+ T&&... args) -> format_to_n_result<OutputIt> {
+ return vformat_to_n(out, n, fmt, fmt::make_format_args(args...));
+}
+
+/** Returns the number of chars in the output of ``format(fmt, args...)``. */
+template <typename... T>
+FMT_NODISCARD FMT_INLINE auto formatted_size(format_string<T...> fmt,
+ T&&... args) -> size_t {
+ auto buf = detail::counting_buffer<>();
+ detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...), {});
+ return buf.count();
+}
+
+FMT_API void vprint(string_view fmt, format_args args);
+FMT_API void vprint(std::FILE* f, string_view fmt, format_args args);
+
+/**
+ \rst
+ Formats ``args`` according to specifications in ``fmt`` and writes the output
+ to ``stdout``.
+
+ **Example**::
+
+ fmt::print("Elapsed time: {0:.2f} seconds", 1.23);
+ \endrst
+ */
+template <typename... T>
+FMT_INLINE void print(format_string<T...> fmt, T&&... args) {
+ const auto& vargs = fmt::make_format_args(args...);
+ return detail::is_utf8() ? vprint(fmt, vargs)
+ : detail::vprint_mojibake(stdout, fmt, vargs);
+}
+
+/**
+ \rst
+ Formats ``args`` according to specifications in ``fmt`` and writes the
+ output to the file ``f``.
+
+ **Example**::
+
+ fmt::print(stderr, "Don't {}!", "panic");
+ \endrst
+ */
+template <typename... T>
+FMT_INLINE void print(std::FILE* f, format_string<T...> fmt, T&&... args) {
+ const auto& vargs = fmt::make_format_args(args...);
+ return detail::is_utf8() ? vprint(f, fmt, vargs)
+ : detail::vprint_mojibake(f, fmt, vargs);
+}
+
+FMT_MODULE_EXPORT_END
+FMT_GCC_PRAGMA("GCC pop_options")
+FMT_END_NAMESPACE
+
+#ifdef FMT_HEADER_ONLY
+# include "format.h"
+#endif
+#endif // FMT_CORE_H_
diff --git a/extern/fmtlib/include/fmt/format-inl.h b/extern/fmtlib/include/fmt/format-inl.h
new file mode 100644
index 00000000000..2c51c50aeb2
--- /dev/null
+++ b/extern/fmtlib/include/fmt/format-inl.h
@@ -0,0 +1,2643 @@
+// Formatting library for C++ - implementation
+//
+// Copyright (c) 2012 - 2016, Victor Zverovich
+// All rights reserved.
+//
+// For the license information refer to format.h.
+
+#ifndef FMT_FORMAT_INL_H_
+#define FMT_FORMAT_INL_H_
+
+#include <algorithm>
+#include <cctype>
+#include <cerrno> // errno
+#include <climits>
+#include <cmath>
+#include <cstdarg>
+#include <cstring> // std::memmove
+#include <cwchar>
+#include <exception>
+
+#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
+# include <locale>
+#endif
+
+#ifdef _WIN32
+# include <io.h> // _isatty
+#endif
+
+#include "format.h"
+
+FMT_BEGIN_NAMESPACE
+namespace detail {
+
+FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
+ // Use unchecked std::fprintf to avoid triggering another assertion when
+ // writing to stderr fails
+ std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
+ // Chosen instead of std::abort to satisfy Clang in CUDA mode during device
+ // code pass.
+ std::terminate();
+}
+
+FMT_FUNC void throw_format_error(const char* message) {
+ FMT_THROW(format_error(message));
+}
+
+#ifndef _MSC_VER
+# define FMT_SNPRINTF snprintf
+#else // _MSC_VER
+inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
+ va_end(args);
+ return result;
+}
+# define FMT_SNPRINTF fmt_snprintf
+#endif // _MSC_VER
+
+FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
+ string_view message) FMT_NOEXCEPT {
+ // Report error code making sure that the output fits into
+ // inline_buffer_size to avoid dynamic memory allocation and potential
+ // bad_alloc.
+ out.try_resize(0);
+ static const char SEP[] = ": ";
+ static const char ERROR_STR[] = "error ";
+ // Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
+ size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
+ auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
+ if (detail::is_negative(error_code)) {
+ abs_value = 0 - abs_value;
+ ++error_code_size;
+ }
+ error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
+ auto it = buffer_appender<char>(out);
+ if (message.size() <= inline_buffer_size - error_code_size)
+ format_to(it, FMT_STRING("{}{}"), message, SEP);
+ format_to(it, FMT_STRING("{}{}"), ERROR_STR, error_code);
+ FMT_ASSERT(out.size() <= inline_buffer_size, "");
+}
+
+FMT_FUNC void report_error(format_func func, int error_code,
+ const char* message) FMT_NOEXCEPT {
+ memory_buffer full_message;
+ func(full_message, error_code, message);
+ // Don't use fwrite_fully because the latter may throw.
+ if (std::fwrite(full_message.data(), full_message.size(), 1, stderr) > 0)
+ std::fputc('\n', stderr);
+}
+
+// A wrapper around fwrite that throws on error.
+inline void fwrite_fully(const void* ptr, size_t size, size_t count,
+ FILE* stream) {
+ size_t written = std::fwrite(ptr, size, count, stream);
+ if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
+}
+
+#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
+template <typename Locale>
+locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
+ static_assert(std::is_same<Locale, std::locale>::value, "");
+}
+
+template <typename Locale> Locale locale_ref::get() const {
+ static_assert(std::is_same<Locale, std::locale>::value, "");
+ return locale_ ? *static_cast<const std::locale*>(locale_) : std::locale();
+}
+
+template <typename Char>
+FMT_FUNC auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char> {
+ auto& facet = std::use_facet<std::numpunct<Char>>(loc.get<std::locale>());
+ auto grouping = facet.grouping();
+ auto thousands_sep = grouping.empty() ? Char() : facet.thousands_sep();
+ return {std::move(grouping), thousands_sep};
+}
+template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
+ return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
+ .decimal_point();
+}
+#else
+template <typename Char>
+FMT_FUNC auto thousands_sep_impl(locale_ref) -> thousands_sep_result<Char> {
+ return {"\03", FMT_STATIC_THOUSANDS_SEPARATOR};
+}
+template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref) {
+ return '.';
+}
+#endif
+} // namespace detail
+
+#if !FMT_MSC_VER
+FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default;
+#endif
+
+FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str,
+ format_args args) {
+ auto ec = std::error_code(error_code, std::generic_category());
+ return std::system_error(ec, vformat(format_str, args));
+}
+
+namespace detail {
+
+template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) {
+ // fallback_uintptr is always stored in little endian.
+ int i = static_cast<int>(sizeof(void*)) - 1;
+ while (i > 0 && n.value[i] == 0) --i;
+ auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
+ return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1;
+}
+
+// log10(2) = 0x0.4d104d427de7fbcc...
+static constexpr uint64_t log10_2_significand = 0x4d104d427de7fbcc;
+
+template <typename T = void> struct basic_impl_data {
+ // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340.
+ // These are generated by support/compute-powers.py.
+ static constexpr uint64_t pow10_significands[87] = {
+ 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76,
+ 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df,
+ 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c,
+ 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5,
+ 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57,
+ 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7,
+ 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e,
+ 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996,
+ 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126,
+ 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053,
+ 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f,
+ 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b,
+ 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06,
+ 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb,
+ 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000,
+ 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984,
+ 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068,
+ 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8,
+ 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758,
+ 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85,
+ 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d,
+ 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25,
+ 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2,
+ 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a,
+ 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410,
+ 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129,
+ 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85,
+ 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841,
+ 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b,
+ };
+
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wnarrowing"
+#endif
+ // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding
+ // to significands above.
+ static constexpr int16_t pow10_exponents[87] = {
+ -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954,
+ -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661,
+ -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369,
+ -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77,
+ -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216,
+ 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508,
+ 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800,
+ 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066};
+#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409
+# pragma GCC diagnostic pop
+#endif
+
+ static constexpr uint64_t power_of_10_64[20] = {
+ 1, FMT_POWERS_OF_10(1ULL), FMT_POWERS_OF_10(1000000000ULL),
+ 10000000000000000000ULL};
+};
+
+// This is a struct rather than an alias to avoid shadowing warnings in gcc.
+struct impl_data : basic_impl_data<> {};
+
+#if __cplusplus < 201703L
+template <typename T>
+constexpr uint64_t basic_impl_data<T>::pow10_significands[];
+template <typename T> constexpr int16_t basic_impl_data<T>::pow10_exponents[];
+template <typename T> constexpr uint64_t basic_impl_data<T>::power_of_10_64[];
+#endif
+
+template <typename T> struct bits {
+ static FMT_CONSTEXPR_DECL const int value =
+ static_cast<int>(sizeof(T) * std::numeric_limits<unsigned char>::digits);
+};
+
+// Returns the number of significand bits in Float excluding the implicit bit.
+template <typename Float> constexpr int num_significand_bits() {
+ // Subtract 1 to account for an implicit most significant bit in the
+ // normalized form.
+ return std::numeric_limits<Float>::digits - 1;
+}
+
+// A floating-point number f * pow(2, e).
+struct fp {
+ uint64_t f;
+ int e;
+
+ static constexpr const int num_significand_bits = bits<decltype(f)>::value;
+
+ constexpr fp() : f(0), e(0) {}
+ constexpr fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {}
+
+ // Constructs fp from an IEEE754 floating-point number. It is a template to
+ // prevent compile errors on systems where n is not IEEE754.
+ template <typename Float> explicit FMT_CONSTEXPR fp(Float n) { assign(n); }
+
+ template <typename Float>
+ using is_supported = bool_constant<sizeof(Float) == sizeof(uint64_t) ||
+ sizeof(Float) == sizeof(uint32_t)>;
+
+ // Assigns d to this and return true iff predecessor is closer than successor.
+ template <typename Float, FMT_ENABLE_IF(is_supported<Float>::value)>
+ FMT_CONSTEXPR bool assign(Float n) {
+ // Assume float is in the format [sign][exponent][significand].
+ const int num_float_significand_bits =
+ detail::num_significand_bits<Float>();
+ const uint64_t implicit_bit = 1ULL << num_float_significand_bits;
+ const uint64_t significand_mask = implicit_bit - 1;
+ constexpr bool is_double = sizeof(Float) == sizeof(uint64_t);
+ auto u = bit_cast<conditional_t<is_double, uint64_t, uint32_t>>(n);
+ f = u & significand_mask;
+ const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask;
+ int biased_e =
+ static_cast<int>((u & exponent_mask) >> num_float_significand_bits);
+ // The predecessor is closer if n is a normalized power of 2 (f == 0) other
+ // than the smallest normalized number (biased_e > 1).
+ bool is_predecessor_closer = f == 0 && biased_e > 1;
+ if (biased_e != 0)
+ f += implicit_bit;
+ else
+ biased_e = 1; // Subnormals use biased exponent 1 (min exponent).
+ const int exponent_bias = std::numeric_limits<Float>::max_exponent - 1;
+ e = biased_e - exponent_bias - num_float_significand_bits;
+ return is_predecessor_closer;
+ }
+
+ template <typename Float, FMT_ENABLE_IF(!is_supported<Float>::value)>
+ bool assign(Float) {
+ FMT_ASSERT(false, "");
+ return false;
+ }
+};
+
+// Normalizes the value converted from double and multiplied by (1 << SHIFT).
+template <int SHIFT = 0> FMT_CONSTEXPR fp normalize(fp value) {
+ // Handle subnormals.
+ const uint64_t implicit_bit = 1ULL << num_significand_bits<double>();
+ const auto shifted_implicit_bit = implicit_bit << SHIFT;
+ while ((value.f & shifted_implicit_bit) == 0) {
+ value.f <<= 1;
+ --value.e;
+ }
+ // Subtract 1 to account for hidden bit.
+ const auto offset =
+ fp::num_significand_bits - num_significand_bits<double>() - SHIFT - 1;
+ value.f <<= offset;
+ value.e -= offset;
+ return value;
+}
+
+inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; }
+
+// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking.
+FMT_CONSTEXPR inline uint64_t multiply(uint64_t lhs, uint64_t rhs) {
+#if FMT_USE_INT128
+ auto product = static_cast<__uint128_t>(lhs) * rhs;
+ auto f = static_cast<uint64_t>(product >> 64);
+ return (static_cast<uint64_t>(product) & (1ULL << 63)) != 0 ? f + 1 : f;
+#else
+ // Multiply 32-bit parts of significands.
+ uint64_t mask = (1ULL << 32) - 1;
+ uint64_t a = lhs >> 32, b = lhs & mask;
+ uint64_t c = rhs >> 32, d = rhs & mask;
+ uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d;
+ // Compute mid 64-bit of result and round.
+ uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31);
+ return ac + (ad >> 32) + (bc >> 32) + (mid >> 32);
+#endif
+}
+
+FMT_CONSTEXPR inline fp operator*(fp x, fp y) {
+ return {multiply(x.f, y.f), x.e + y.e + 64};
+}
+
+// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its
+// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`.
+FMT_CONSTEXPR inline fp get_cached_power(int min_exponent,
+ int& pow10_exponent) {
+ const int shift = 32;
+ const auto significand = static_cast<int64_t>(log10_2_significand);
+ int index = static_cast<int>(
+ ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) +
+ ((int64_t(1) << shift) - 1)) // ceil
+ >> 32 // arithmetic shift
+ );
+ // Decimal exponent of the first (smallest) cached power of 10.
+ const int first_dec_exp = -348;
+ // Difference between 2 consecutive decimal exponents in cached powers of 10.
+ const int dec_exp_step = 8;
+ index = (index - first_dec_exp - 1) / dec_exp_step + 1;
+ pow10_exponent = first_dec_exp + index * dec_exp_step;
+ return {impl_data::pow10_significands[index],
+ impl_data::pow10_exponents[index]};
+}
+
+// A simple accumulator to hold the sums of terms in bigint::square if uint128_t
+// is not available.
+struct accumulator {
+ uint64_t lower;
+ uint64_t upper;
+
+ constexpr accumulator() : lower(0), upper(0) {}
+ constexpr explicit operator uint32_t() const {
+ return static_cast<uint32_t>(lower);
+ }
+
+ FMT_CONSTEXPR void operator+=(uint64_t n) {
+ lower += n;
+ if (lower < n) ++upper;
+ }
+ FMT_CONSTEXPR void operator>>=(int shift) {
+ FMT_ASSERT(shift == 32, "");
+ (void)shift;
+ lower = (upper << 32) | (lower >> 32);
+ upper >>= 32;
+ }
+};
+
+class bigint {
+ private:
+ // A bigint is stored as an array of bigits (big digits), with bigit at index
+ // 0 being the least significant one.
+ using bigit = uint32_t;
+ using double_bigit = uint64_t;
+ enum { bigits_capacity = 32 };
+ basic_memory_buffer<bigit, bigits_capacity> bigits_;
+ int exp_;
+
+ FMT_CONSTEXPR20 bigit operator[](int index) const {
+ return bigits_[to_unsigned(index)];
+ }
+ FMT_CONSTEXPR20 bigit& operator[](int index) {
+ return bigits_[to_unsigned(index)];
+ }
+
+ static FMT_CONSTEXPR_DECL const int bigit_bits = bits<bigit>::value;
+
+ friend struct formatter<bigint>;
+
+ FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) {
+ auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
+ (*this)[index] = static_cast<bigit>(result);
+ borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
+ }
+
+ FMT_CONSTEXPR20 void remove_leading_zeros() {
+ int num_bigits = static_cast<int>(bigits_.size()) - 1;
+ while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
+ bigits_.resize(to_unsigned(num_bigits + 1));
+ }
+
+ // Computes *this -= other assuming aligned bigints and *this >= other.
+ FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) {
+ FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints");
+ FMT_ASSERT(compare(*this, other) >= 0, "");
+ bigit borrow = 0;
+ int i = other.exp_ - exp_;
+ for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
+ subtract_bigits(i, other.bigits_[j], borrow);
+ while (borrow > 0) subtract_bigits(i, 0, borrow);
+ remove_leading_zeros();
+ }
+
+ FMT_CONSTEXPR20 void multiply(uint32_t value) {
+ const double_bigit wide_value = value;
+ bigit carry = 0;
+ for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
+ double_bigit result = bigits_[i] * wide_value + carry;
+ bigits_[i] = static_cast<bigit>(result);
+ carry = static_cast<bigit>(result >> bigit_bits);
+ }
+ if (carry != 0) bigits_.push_back(carry);
+ }
+
+ FMT_CONSTEXPR20 void multiply(uint64_t value) {
+ const bigit mask = ~bigit(0);
+ const double_bigit lower = value & mask;
+ const double_bigit upper = value >> bigit_bits;
+ double_bigit carry = 0;
+ for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
+ double_bigit result = bigits_[i] * lower + (carry & mask);
+ carry =
+ bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits);
+ bigits_[i] = static_cast<bigit>(result);
+ }
+ while (carry != 0) {
+ bigits_.push_back(carry & mask);
+ carry >>= bigit_bits;
+ }
+ }
+
+ public:
+ FMT_CONSTEXPR20 bigint() : exp_(0) {}
+ explicit bigint(uint64_t n) { assign(n); }
+ FMT_CONSTEXPR20 ~bigint() {
+ FMT_ASSERT(bigits_.capacity() <= bigits_capacity, "");
+ }
+
+ bigint(const bigint&) = delete;
+ void operator=(const bigint&) = delete;
+
+ FMT_CONSTEXPR20 void assign(const bigint& other) {
+ auto size = other.bigits_.size();
+ bigits_.resize(size);
+ auto data = other.bigits_.data();
+ std::copy(data, data + size, make_checked(bigits_.data(), size));
+ exp_ = other.exp_;
+ }
+
+ FMT_CONSTEXPR20 void assign(uint64_t n) {
+ size_t num_bigits = 0;
+ do {
+ bigits_[num_bigits++] = n & ~bigit(0);
+ n >>= bigit_bits;
+ } while (n != 0);
+ bigits_.resize(num_bigits);
+ exp_ = 0;
+ }
+
+ FMT_CONSTEXPR20 int num_bigits() const {
+ return static_cast<int>(bigits_.size()) + exp_;
+ }
+
+ FMT_NOINLINE FMT_CONSTEXPR20 bigint& operator<<=(int shift) {
+ FMT_ASSERT(shift >= 0, "");
+ exp_ += shift / bigit_bits;
+ shift %= bigit_bits;
+ if (shift == 0) return *this;
+ bigit carry = 0;
+ for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
+ bigit c = bigits_[i] >> (bigit_bits - shift);
+ bigits_[i] = (bigits_[i] << shift) + carry;
+ carry = c;
+ }
+ if (carry != 0) bigits_.push_back(carry);
+ return *this;
+ }
+
+ template <typename Int> FMT_CONSTEXPR20 bigint& operator*=(Int value) {
+ FMT_ASSERT(value > 0, "");
+ multiply(uint32_or_64_or_128_t<Int>(value));
+ return *this;
+ }
+
+ friend FMT_CONSTEXPR20 int compare(const bigint& lhs, const bigint& rhs) {
+ int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits();
+ if (num_lhs_bigits != num_rhs_bigits)
+ return num_lhs_bigits > num_rhs_bigits ? 1 : -1;
+ int i = static_cast<int>(lhs.bigits_.size()) - 1;
+ int j = static_cast<int>(rhs.bigits_.size()) - 1;
+ int end = i - j;
+ if (end < 0) end = 0;
+ for (; i >= end; --i, --j) {
+ bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
+ if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
+ }
+ if (i != j) return i > j ? 1 : -1;
+ return 0;
+ }
+
+ // Returns compare(lhs1 + lhs2, rhs).
+ friend FMT_CONSTEXPR20 int add_compare(const bigint& lhs1, const bigint& lhs2,
+ const bigint& rhs) {
+ int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits());
+ int num_rhs_bigits = rhs.num_bigits();
+ if (max_lhs_bigits + 1 < num_rhs_bigits) return -1;
+ if (max_lhs_bigits > num_rhs_bigits) return 1;
+ auto get_bigit = [](const bigint& n, int i) -> bigit {
+ return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0;
+ };
+ double_bigit borrow = 0;
+ int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_);
+ for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
+ double_bigit sum =
+ static_cast<double_bigit>(get_bigit(lhs1, i)) + get_bigit(lhs2, i);
+ bigit rhs_bigit = get_bigit(rhs, i);
+ if (sum > rhs_bigit + borrow) return 1;
+ borrow = rhs_bigit + borrow - sum;
+ if (borrow > 1) return -1;
+ borrow <<= bigit_bits;
+ }
+ return borrow != 0 ? -1 : 0;
+ }
+
+ // Assigns pow(10, exp) to this bigint.
+ FMT_CONSTEXPR20 void assign_pow10(int exp) {
+ FMT_ASSERT(exp >= 0, "");
+ if (exp == 0) return assign(1);
+ // Find the top bit.
+ int bitmask = 1;
+ while (exp >= bitmask) bitmask <<= 1;
+ bitmask >>= 1;
+ // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by
+ // repeated squaring and multiplication.
+ assign(5);
+ bitmask >>= 1;
+ while (bitmask != 0) {
+ square();
+ if ((exp & bitmask) != 0) *this *= 5;
+ bitmask >>= 1;
+ }
+ *this <<= exp; // Multiply by pow(2, exp) by shifting.
+ }
+
+ FMT_CONSTEXPR20 void square() {
+ int num_bigits = static_cast<int>(bigits_.size());
+ int num_result_bigits = 2 * num_bigits;
+ basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
+ bigits_.resize(to_unsigned(num_result_bigits));
+ using accumulator_t = conditional_t<FMT_USE_INT128, uint128_t, accumulator>;
+ auto sum = accumulator_t();
+ for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
+ // Compute bigit at position bigit_index of the result by adding
+ // cross-product terms n[i] * n[j] such that i + j == bigit_index.
+ for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
+ // Most terms are multiplied twice which can be optimized in the future.
+ sum += static_cast<double_bigit>(n[i]) * n[j];
+ }
+ (*this)[bigit_index] = static_cast<bigit>(sum);
+ sum >>= bits<bigit>::value; // Compute the carry.
+ }
+ // Do the same for the top half.
+ for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
+ ++bigit_index) {
+ for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
+ sum += static_cast<double_bigit>(n[i++]) * n[j--];
+ (*this)[bigit_index] = static_cast<bigit>(sum);
+ sum >>= bits<bigit>::value;
+ }
+ remove_leading_zeros();
+ exp_ *= 2;
+ }
+
+ // If this bigint has a bigger exponent than other, adds trailing zero to make
+ // exponents equal. This simplifies some operations such as subtraction.
+ FMT_CONSTEXPR20 void align(const bigint& other) {
+ int exp_difference = exp_ - other.exp_;
+ if (exp_difference <= 0) return;
+ int num_bigits = static_cast<int>(bigits_.size());
+ bigits_.resize(to_unsigned(num_bigits + exp_difference));
+ for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j)
+ bigits_[j] = bigits_[i];
+ std::uninitialized_fill_n(bigits_.data(), exp_difference, 0);
+ exp_ -= exp_difference;
+ }
+
+ // Divides this bignum by divisor, assigning the remainder to this and
+ // returning the quotient.
+ FMT_CONSTEXPR20 int divmod_assign(const bigint& divisor) {
+ FMT_ASSERT(this != &divisor, "");
+ if (compare(*this, divisor) < 0) return 0;
+ FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, "");
+ align(divisor);
+ int quotient = 0;
+ do {
+ subtract_aligned(divisor);
+ ++quotient;
+ } while (compare(*this, divisor) >= 0);
+ return quotient;
+ }
+};
+
+enum class round_direction { unknown, up, down };
+
+// Given the divisor (normally a power of 10), the remainder = v % divisor for
+// some number v and the error, returns whether v should be rounded up, down, or
+// whether the rounding direction can't be determined due to error.
+// error should be less than divisor / 2.
+FMT_CONSTEXPR inline round_direction get_round_direction(uint64_t divisor,
+ uint64_t remainder,
+ uint64_t error) {
+ FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow.
+ FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow.
+ FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow.
+ // Round down if (remainder + error) * 2 <= divisor.
+ if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2)
+ return round_direction::down;
+ // Round up if (remainder - error) * 2 >= divisor.
+ if (remainder >= error &&
+ remainder - error >= divisor - (remainder - error)) {
+ return round_direction::up;
+ }
+ return round_direction::unknown;
+}
+
+namespace digits {
+enum result {
+ more, // Generate more digits.
+ done, // Done generating digits.
+ error // Digit generation cancelled due to an error.
+};
+}
+
+struct gen_digits_handler {
+ char* buf;
+ int size;
+ int precision;
+ int exp10;
+ bool fixed;
+
+ FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor,
+ uint64_t remainder, uint64_t error,
+ bool integral) {
+ FMT_ASSERT(remainder < divisor, "");
+ buf[size++] = digit;
+ if (!integral && error >= remainder) return digits::error;
+ if (size < precision) return digits::more;
+ if (!integral) {
+ // Check if error * 2 < divisor with overflow prevention.
+ // The check is not needed for the integral part because error = 1
+ // and divisor > (1 << 32) there.
+ if (error >= divisor || error >= divisor - error) return digits::error;
+ } else {
+ FMT_ASSERT(error == 1 && divisor > 2, "");
+ }
+ auto dir = get_round_direction(divisor, remainder, error);
+ if (dir != round_direction::up)
+ return dir == round_direction::down ? digits::done : digits::error;
+ ++buf[size - 1];
+ for (int i = size - 1; i > 0 && buf[i] > '9'; --i) {
+ buf[i] = '0';
+ ++buf[i - 1];
+ }
+ if (buf[0] > '9') {
+ buf[0] = '1';
+ if (fixed)
+ buf[size++] = '0';
+ else
+ ++exp10;
+ }
+ return digits::done;
+ }
+};
+
+// Generates output using the Grisu digit-gen algorithm.
+// error: the size of the region (lower, upper) outside of which numbers
+// definitely do not round to value (Delta in Grisu3).
+FMT_INLINE FMT_CONSTEXPR20 digits::result grisu_gen_digits(
+ fp value, uint64_t error, int& exp, gen_digits_handler& handler) {
+ const fp one(1ULL << -value.e, value.e);
+ // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be
+ // zero because it contains a product of two 64-bit numbers with MSB set (due
+ // to normalization) - 1, shifted right by at most 60 bits.
+ auto integral = static_cast<uint32_t>(value.f >> -one.e);
+ FMT_ASSERT(integral != 0, "");
+ FMT_ASSERT(integral == value.f >> -one.e, "");
+ // The fractional part of scaled value (p2 in Grisu) c = value % one.
+ uint64_t fractional = value.f & (one.f - 1);
+ exp = count_digits(integral); // kappa in Grisu.
+ // Non-fixed formats require at least one digit and no precision adjustment.
+ if (handler.fixed) {
+ // Adjust fixed precision by exponent because it is relative to decimal
+ // point.
+ int precision_offset = exp + handler.exp10;
+ if (precision_offset > 0 &&
+ handler.precision > max_value<int>() - precision_offset) {
+ FMT_THROW(format_error("number is too big"));
+ }
+ handler.precision += precision_offset;
+ // Check if precision is satisfied just by leading zeros, e.g.
+ // format("{:.2f}", 0.001) gives "0.00" without generating any digits.
+ if (handler.precision <= 0) {
+ if (handler.precision < 0) return digits::done;
+ // Divide by 10 to prevent overflow.
+ uint64_t divisor = impl_data::power_of_10_64[exp - 1] << -one.e;
+ auto dir = get_round_direction(divisor, value.f / 10, error * 10);
+ if (dir == round_direction::unknown) return digits::error;
+ handler.buf[handler.size++] = dir == round_direction::up ? '1' : '0';
+ return digits::done;
+ }
+ }
+ // Generate digits for the integral part. This can produce up to 10 digits.
+ do {
+ uint32_t digit = 0;
+ auto divmod_integral = [&](uint32_t divisor) {
+ digit = integral / divisor;
+ integral %= divisor;
+ };
+ // This optimization by Milo Yip reduces the number of integer divisions by
+ // one per iteration.
+ switch (exp) {
+ case 10:
+ divmod_integral(1000000000);
+ break;
+ case 9:
+ divmod_integral(100000000);
+ break;
+ case 8:
+ divmod_integral(10000000);
+ break;
+ case 7:
+ divmod_integral(1000000);
+ break;
+ case 6:
+ divmod_integral(100000);
+ break;
+ case 5:
+ divmod_integral(10000);
+ break;
+ case 4:
+ divmod_integral(1000);
+ break;
+ case 3:
+ divmod_integral(100);
+ break;
+ case 2:
+ divmod_integral(10);
+ break;
+ case 1:
+ digit = integral;
+ integral = 0;
+ break;
+ default:
+ FMT_ASSERT(false, "invalid number of digits");
+ }
+ --exp;
+ auto remainder = (static_cast<uint64_t>(integral) << -one.e) + fractional;
+ auto result = handler.on_digit(static_cast<char>('0' + digit),
+ impl_data::power_of_10_64[exp] << -one.e,
+ remainder, error, true);
+ if (result != digits::more) return result;
+ } while (exp > 0);
+ // Generate digits for the fractional part.
+ for (;;) {
+ fractional *= 10;
+ error *= 10;
+ char digit = static_cast<char>('0' + (fractional >> -one.e));
+ fractional &= one.f - 1;
+ --exp;
+ auto result = handler.on_digit(digit, one.f, fractional, error, false);
+ if (result != digits::more) return result;
+ }
+}
+
+// A 128-bit integer type used internally,
+struct uint128_wrapper {
+ uint128_wrapper() = default;
+
+#if FMT_USE_INT128
+ uint128_t internal_;
+
+ constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
+ : internal_{static_cast<uint128_t>(low) |
+ (static_cast<uint128_t>(high) << 64)} {}
+
+ constexpr uint128_wrapper(uint128_t u) : internal_{u} {}
+
+ constexpr uint64_t high() const FMT_NOEXCEPT {
+ return uint64_t(internal_ >> 64);
+ }
+ constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); }
+
+ uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
+ internal_ += n;
+ return *this;
+ }
+#else
+ uint64_t high_;
+ uint64_t low_;
+
+ constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT
+ : high_{high},
+ low_{low} {}
+
+ constexpr uint64_t high() const FMT_NOEXCEPT { return high_; }
+ constexpr uint64_t low() const FMT_NOEXCEPT { return low_; }
+
+ uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT {
+# if defined(_MSC_VER) && defined(_M_X64)
+ unsigned char carry = _addcarry_u64(0, low_, n, &low_);
+ _addcarry_u64(carry, high_, 0, &high_);
+ return *this;
+# else
+ uint64_t sum = low_ + n;
+ high_ += (sum < low_ ? 1 : 0);
+ low_ = sum;
+ return *this;
+# endif
+ }
+#endif
+};
+
+// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox.
+namespace dragonbox {
+// Computes 128-bit result of multiplication of two 64-bit unsigned integers.
+inline uint128_wrapper umul128(uint64_t x, uint64_t y) FMT_NOEXCEPT {
+#if FMT_USE_INT128
+ return static_cast<uint128_t>(x) * static_cast<uint128_t>(y);
+#elif defined(_MSC_VER) && defined(_M_X64)
+ uint128_wrapper result;
+ result.low_ = _umul128(x, y, &result.high_);
+ return result;
+#else
+ const uint64_t mask = (uint64_t(1) << 32) - uint64_t(1);
+
+ uint64_t a = x >> 32;
+ uint64_t b = x & mask;
+ uint64_t c = y >> 32;
+ uint64_t d = y & mask;
+
+ uint64_t ac = a * c;
+ uint64_t bc = b * c;
+ uint64_t ad = a * d;
+ uint64_t bd = b * d;
+
+ uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask);
+
+ return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32),
+ (intermediate << 32) + (bd & mask)};
+#endif
+}
+
+// Computes upper 64 bits of multiplication of two 64-bit unsigned integers.
+inline uint64_t umul128_upper64(uint64_t x, uint64_t y) FMT_NOEXCEPT {
+#if FMT_USE_INT128
+ auto p = static_cast<uint128_t>(x) * static_cast<uint128_t>(y);
+ return static_cast<uint64_t>(p >> 64);
+#elif defined(_MSC_VER) && defined(_M_X64)
+ return __umulh(x, y);
+#else
+ return umul128(x, y).high();
+#endif
+}
+
+// Computes upper 64 bits of multiplication of a 64-bit unsigned integer and a
+// 128-bit unsigned integer.
+inline uint64_t umul192_upper64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT {
+ uint128_wrapper g0 = umul128(x, y.high());
+ g0 += umul128_upper64(x, y.low());
+ return g0.high();
+}
+
+// Computes upper 32 bits of multiplication of a 32-bit unsigned integer and a
+// 64-bit unsigned integer.
+inline uint32_t umul96_upper32(uint32_t x, uint64_t y) FMT_NOEXCEPT {
+ return static_cast<uint32_t>(umul128_upper64(x, y));
+}
+
+// Computes middle 64 bits of multiplication of a 64-bit unsigned integer and a
+// 128-bit unsigned integer.
+inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT {
+ uint64_t g01 = x * y.high();
+ uint64_t g10 = umul128_upper64(x, y.low());
+ return g01 + g10;
+}
+
+// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a
+// 64-bit unsigned integer.
+inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT {
+ return x * y;
+}
+
+// Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from
+// https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4.
+inline int floor_log10_pow2(int e) FMT_NOEXCEPT {
+ FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent");
+ const int shift = 22;
+ return (e * static_cast<int>(log10_2_significand >> (64 - shift))) >> shift;
+}
+
+// Various fast log computations.
+inline int floor_log2_pow10(int e) FMT_NOEXCEPT {
+ FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent");
+ const uint64_t log2_10_integer_part = 3;
+ const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9;
+ const int shift_amount = 19;
+ return (e * static_cast<int>(
+ (log2_10_integer_part << shift_amount) |
+ (log2_10_fractional_digits >> (64 - shift_amount)))) >>
+ shift_amount;
+}
+inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT {
+ FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent");
+ const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375;
+ const int shift_amount = 22;
+ return (e * static_cast<int>(log10_2_significand >> (64 - shift_amount)) -
+ static_cast<int>(log10_4_over_3_fractional_digits >>
+ (64 - shift_amount))) >>
+ shift_amount;
+}
+
+// Returns true iff x is divisible by pow(2, exp).
+inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT {
+ FMT_ASSERT(exp >= 1, "");
+ FMT_ASSERT(x != 0, "");
+#ifdef FMT_BUILTIN_CTZ
+ return FMT_BUILTIN_CTZ(x) >= exp;
+#else
+ return exp < num_bits<uint32_t>() && x == ((x >> exp) << exp);
+#endif
+}
+inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT {
+ FMT_ASSERT(exp >= 1, "");
+ FMT_ASSERT(x != 0, "");
+#ifdef FMT_BUILTIN_CTZLL
+ return FMT_BUILTIN_CTZLL(x) >= exp;
+#else
+ return exp < num_bits<uint64_t>() && x == ((x >> exp) << exp);
+#endif
+}
+
+// Table entry type for divisibility test.
+template <typename T> struct divtest_table_entry {
+ T mod_inv;
+ T max_quotient;
+};
+
+// Returns true iff x is divisible by pow(5, exp).
+inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT {
+ FMT_ASSERT(exp <= 10, "too large exponent");
+ static constexpr const divtest_table_entry<uint32_t> divtest_table[] = {
+ {0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333},
+ {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba},
+ {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5},
+ {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf},
+ {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897},
+ {0x3ed61f49, 0x000001b7}};
+ return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient;
+}
+inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT {
+ FMT_ASSERT(exp <= 23, "too large exponent");
+ static constexpr const divtest_table_entry<uint64_t> divtest_table[] = {
+ {0x0000000000000001, 0xffffffffffffffff},
+ {0xcccccccccccccccd, 0x3333333333333333},
+ {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70},
+ {0x1cac083126e978d5, 0x020c49ba5e353f7c},
+ {0xd288ce703afb7e91, 0x0068db8bac710cb2},
+ {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0},
+ {0x790fb65668c26139, 0x000431bde82d7b63},
+ {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a},
+ {0xc767074b22e90e21, 0x00002af31dc46118},
+ {0x8e47ce423a2e9c6d, 0x0000089705f4136b},
+ {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b},
+ {0x0fee64690c913975, 0x00000057f5ff85e5},
+ {0x3662e0e1cf503eb1, 0x000000119799812d},
+ {0xa47a2cf9f6433fbd, 0x0000000384b84d09},
+ {0x54186f653140a659, 0x00000000b424dc35},
+ {0x7738164770402145, 0x0000000024075f3d},
+ {0xe4a4d1417cd9a041, 0x000000000734aca5},
+ {0xc75429d9e5c5200d, 0x000000000170ef54},
+ {0xc1773b91fac10669, 0x000000000049c977},
+ {0x26b172506559ce15, 0x00000000000ec1e4},
+ {0xd489e3a9addec2d1, 0x000000000002f394},
+ {0x90e860bb892c8d5d, 0x000000000000971d},
+ {0x502e79bf1b6f4f79, 0x0000000000001e39},
+ {0xdcd618596be30fe5, 0x000000000000060b}};
+ return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient;
+}
+
+// Replaces n by floor(n / pow(5, N)) returning true if and only if n is
+// divisible by pow(5, N).
+// Precondition: n <= 2 * pow(5, N + 1).
+template <int N>
+bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT {
+ static constexpr struct {
+ uint32_t magic_number;
+ int bits_for_comparison;
+ uint32_t threshold;
+ int shift_amount;
+ } infos[] = {{0xcccd, 16, 0x3333, 18}, {0xa429, 8, 0x0a, 20}};
+ constexpr auto info = infos[N - 1];
+ n *= info.magic_number;
+ const uint32_t comparison_mask = (1u << info.bits_for_comparison) - 1;
+ bool result = (n & comparison_mask) <= info.threshold;
+ n >>= info.shift_amount;
+ return result;
+}
+
+// Computes floor(n / pow(10, N)) for small n and N.
+// Precondition: n <= pow(10, N + 1).
+template <int N> uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT {
+ static constexpr struct {
+ uint32_t magic_number;
+ int shift_amount;
+ uint32_t divisor_times_10;
+ } infos[] = {{0xcccd, 19, 100}, {0xa3d8, 22, 1000}};
+ constexpr auto info = infos[N - 1];
+ FMT_ASSERT(n <= info.divisor_times_10, "n is too large");
+ return n * info.magic_number >> info.shift_amount;
+}
+
+// Computes floor(n / 10^(kappa + 1)) (float)
+inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) FMT_NOEXCEPT {
+ return n / float_info<float>::big_divisor;
+}
+// Computes floor(n / 10^(kappa + 1)) (double)
+inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT {
+ return umul128_upper64(n, 0x83126e978d4fdf3c) >> 9;
+}
+
+// Various subroutines using pow10 cache
+template <class T> struct cache_accessor;
+
+template <> struct cache_accessor<float> {
+ using carrier_uint = float_info<float>::carrier_uint;
+ using cache_entry_type = uint64_t;
+
+ static uint64_t get_cached_power(int k) FMT_NOEXCEPT {
+ FMT_ASSERT(k >= float_info<float>::min_k && k <= float_info<float>::max_k,
+ "k is out of range");
+ static constexpr const uint64_t pow10_significands[] = {
+ 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f,
+ 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb,
+ 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28,
+ 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb,
+ 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a,
+ 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810,
+ 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff,
+ 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd,
+ 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424,
+ 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b,
+ 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000,
+ 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000,
+ 0xc350000000000000, 0xf424000000000000, 0x9896800000000000,
+ 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000,
+ 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000,
+ 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000,
+ 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000,
+ 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000,
+ 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0,
+ 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984,
+ 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296,
+ 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6,
+ 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20,
+ 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd,
+ 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719,
+ 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e};
+ return pow10_significands[k - float_info<float>::min_k];
+ }
+
+ static carrier_uint compute_mul(carrier_uint u,
+ const cache_entry_type& cache) FMT_NOEXCEPT {
+ return umul96_upper32(u, cache);
+ }
+
+ static uint32_t compute_delta(const cache_entry_type& cache,
+ int beta_minus_1) FMT_NOEXCEPT {
+ return static_cast<uint32_t>(cache >> (64 - 1 - beta_minus_1));
+ }
+
+ static bool compute_mul_parity(carrier_uint two_f,
+ const cache_entry_type& cache,
+ int beta_minus_1) FMT_NOEXCEPT {
+ FMT_ASSERT(beta_minus_1 >= 1, "");
+ FMT_ASSERT(beta_minus_1 < 64, "");
+
+ return ((umul96_lower64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0;
+ }
+
+ static carrier_uint compute_left_endpoint_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return static_cast<carrier_uint>(
+ (cache - (cache >> (float_info<float>::significand_bits + 2))) >>
+ (64 - float_info<float>::significand_bits - 1 - beta_minus_1));
+ }
+
+ static carrier_uint compute_right_endpoint_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return static_cast<carrier_uint>(
+ (cache + (cache >> (float_info<float>::significand_bits + 1))) >>
+ (64 - float_info<float>::significand_bits - 1 - beta_minus_1));
+ }
+
+ static carrier_uint compute_round_up_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return (static_cast<carrier_uint>(
+ cache >>
+ (64 - float_info<float>::significand_bits - 2 - beta_minus_1)) +
+ 1) /
+ 2;
+ }
+};
+
+template <> struct cache_accessor<double> {
+ using carrier_uint = float_info<double>::carrier_uint;
+ using cache_entry_type = uint128_wrapper;
+
+ static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT {
+ FMT_ASSERT(k >= float_info<double>::min_k && k <= float_info<double>::max_k,
+ "k is out of range");
+
+ static constexpr const uint128_wrapper pow10_significands[] = {
+#if FMT_USE_FULL_CACHE_DRAGONBOX
+ {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
+ {0x9faacf3df73609b1, 0x77b191618c54e9ad},
+ {0xc795830d75038c1d, 0xd59df5b9ef6a2418},
+ {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e},
+ {0x9becce62836ac577, 0x4ee367f9430aec33},
+ {0xc2e801fb244576d5, 0x229c41f793cda740},
+ {0xf3a20279ed56d48a, 0x6b43527578c11110},
+ {0x9845418c345644d6, 0x830a13896b78aaaa},
+ {0xbe5691ef416bd60c, 0x23cc986bc656d554},
+ {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9},
+ {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa},
+ {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54},
+ {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69},
+ {0x91376c36d99995be, 0x23100809b9c21fa2},
+ {0xb58547448ffffb2d, 0xabd40a0c2832a78b},
+ {0xe2e69915b3fff9f9, 0x16c90c8f323f516d},
+ {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4},
+ {0xb1442798f49ffb4a, 0x99cd11cfdf41779d},
+ {0xdd95317f31c7fa1d, 0x40405643d711d584},
+ {0x8a7d3eef7f1cfc52, 0x482835ea666b2573},
+ {0xad1c8eab5ee43b66, 0xda3243650005eed0},
+ {0xd863b256369d4a40, 0x90bed43e40076a83},
+ {0x873e4f75e2224e68, 0x5a7744a6e804a292},
+ {0xa90de3535aaae202, 0x711515d0a205cb37},
+ {0xd3515c2831559a83, 0x0d5a5b44ca873e04},
+ {0x8412d9991ed58091, 0xe858790afe9486c3},
+ {0xa5178fff668ae0b6, 0x626e974dbe39a873},
+ {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
+ {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a},
+ {0xa139029f6a239f72, 0x1c1fffc1ebc44e81},
+ {0xc987434744ac874e, 0xa327ffb266b56221},
+ {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9},
+ {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa},
+ {0xc4ce17b399107c22, 0xcb550fb4384d21d4},
+ {0xf6019da07f549b2b, 0x7e2a53a146606a49},
+ {0x99c102844f94e0fb, 0x2eda7444cbfc426e},
+ {0xc0314325637a1939, 0xfa911155fefb5309},
+ {0xf03d93eebc589f88, 0x793555ab7eba27cb},
+ {0x96267c7535b763b5, 0x4bc1558b2f3458df},
+ {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17},
+ {0xea9c227723ee8bcb, 0x465e15a979c1cadd},
+ {0x92a1958a7675175f, 0x0bfacd89ec191eca},
+ {0xb749faed14125d36, 0xcef980ec671f667c},
+ {0xe51c79a85916f484, 0x82b7e12780e7401b},
+ {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811},
+ {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16},
+ {0xdfbdcece67006ac9, 0x67a791e093e1d49b},
+ {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1},
+ {0xaecc49914078536d, 0x58fae9f773886e19},
+ {0xda7f5bf590966848, 0xaf39a475506a899f},
+ {0x888f99797a5e012d, 0x6d8406c952429604},
+ {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84},
+ {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65},
+ {0x855c3be0a17fcd26, 0x5cf2eea09a550680},
+ {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
+ {0xd0601d8efc57b08b, 0xf13b94daf124da27},
+ {0x823c12795db6ce57, 0x76c53d08d6b70859},
+ {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f},
+ {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a},
+ {0xfe5d54150b090b02, 0xd3f93b35435d7c4d},
+ {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0},
+ {0xc6b8e9b0709f109a, 0x359ab6419ca1091c},
+ {0xf867241c8cc6d4c0, 0xc30163d203c94b63},
+ {0x9b407691d7fc44f8, 0x79e0de63425dcf1e},
+ {0xc21094364dfb5636, 0x985915fc12f542e5},
+ {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e},
+ {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43},
+ {0xbd8430bd08277231, 0x50c6ff782a838354},
+ {0xece53cec4a314ebd, 0xa4f8bf5635246429},
+ {0x940f4613ae5ed136, 0x871b7795e136be9a},
+ {0xb913179899f68584, 0x28e2557b59846e40},
+ {0xe757dd7ec07426e5, 0x331aeada2fe589d0},
+ {0x9096ea6f3848984f, 0x3ff0d2c85def7622},
+ {0xb4bca50b065abe63, 0x0fed077a756b53aa},
+ {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895},
+ {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d},
+ {0xb080392cc4349dec, 0xbd8d794d96aacfb4},
+ {0xdca04777f541c567, 0xecf0d7a0fc5583a1},
+ {0x89e42caaf9491b60, 0xf41686c49db57245},
+ {0xac5d37d5b79b6239, 0x311c2875c522ced6},
+ {0xd77485cb25823ac7, 0x7d633293366b828c},
+ {0x86a8d39ef77164bc, 0xae5dff9c02033198},
+ {0xa8530886b54dbdeb, 0xd9f57f830283fdfd},
+ {0xd267caa862a12d66, 0xd072df63c324fd7c},
+ {0x8380dea93da4bc60, 0x4247cb9e59f71e6e},
+ {0xa46116538d0deb78, 0x52d9be85f074e609},
+ {0xcd795be870516656, 0x67902e276c921f8c},
+ {0x806bd9714632dff6, 0x00ba1cd8a3db53b7},
+ {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5},
+ {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce},
+ {0xfad2a4b13d1b5d6c, 0x796b805720085f82},
+ {0x9cc3a6eec6311a63, 0xcbe3303674053bb1},
+ {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d},
+ {0xf4f1b4d515acb93b, 0xee92fb5515482d45},
+ {0x991711052d8bf3c5, 0x751bdd152d4d1c4b},
+ {0xbf5cd54678eef0b6, 0xd262d45a78a0635e},
+ {0xef340a98172aace4, 0x86fb897116c87c35},
+ {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1},
+ {0xbae0a846d2195712, 0x8974836059cca10a},
+ {0xe998d258869facd7, 0x2bd1a438703fc94c},
+ {0x91ff83775423cc06, 0x7b6306a34627ddd0},
+ {0xb67f6455292cbf08, 0x1a3bc84c17b1d543},
+ {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94},
+ {0x8e938662882af53e, 0x547eb47b7282ee9d},
+ {0xb23867fb2a35b28d, 0xe99e619a4f23aa44},
+ {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5},
+ {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05},
+ {0xae0b158b4738705e, 0x9624ab50b148d446},
+ {0xd98ddaee19068c76, 0x3badd624dd9b0958},
+ {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7},
+ {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d},
+ {0xd47487cc8470652b, 0x7647c32000696720},
+ {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074},
+ {0xa5fb0a17c777cf09, 0xf468107100525891},
+ {0xcf79cc9db955c2cc, 0x7182148d4066eeb5},
+ {0x81ac1fe293d599bf, 0xc6f14cd848405531},
+ {0xa21727db38cb002f, 0xb8ada00e5a506a7d},
+ {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d},
+ {0xfd442e4688bd304a, 0x908f4a166d1da664},
+ {0x9e4a9cec15763e2e, 0x9a598e4e043287ff},
+ {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe},
+ {0xf7549530e188c128, 0xd12bee59e68ef47d},
+ {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf},
+ {0xc13a148e3032d6e7, 0xe36a52363c1faf02},
+ {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2},
+ {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba},
+ {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8},
+ {0xebdf661791d60f56, 0x111b495b3464ad22},
+ {0x936b9fcebb25c995, 0xcab10dd900beec35},
+ {0xb84687c269ef3bfb, 0x3d5d514f40eea743},
+ {0xe65829b3046b0afa, 0x0cb4a5a3112a5113},
+ {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac},
+ {0xb3f4e093db73a093, 0x59ed216765690f57},
+ {0xe0f218b8d25088b8, 0x306869c13ec3532d},
+ {0x8c974f7383725573, 0x1e414218c73a13fc},
+ {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
+ {0xdbac6c247d62a583, 0xdf45f746b74abf3a},
+ {0x894bc396ce5da772, 0x6b8bba8c328eb784},
+ {0xab9eb47c81f5114f, 0x066ea92f3f326565},
+ {0xd686619ba27255a2, 0xc80a537b0efefebe},
+ {0x8613fd0145877585, 0xbd06742ce95f5f37},
+ {0xa798fc4196e952e7, 0x2c48113823b73705},
+ {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6},
+ {0x82ef85133de648c4, 0x9a984d73dbe722fc},
+ {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb},
+ {0xcc963fee10b7d1b3, 0x318df905079926a9},
+ {0xffbbcfe994e5c61f, 0xfdf17746497f7053},
+ {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634},
+ {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1},
+ {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1},
+ {0x9c1661a651213e2d, 0x06bea10ca65c084f},
+ {0xc31bfa0fe5698db8, 0x486e494fcff30a63},
+ {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb},
+ {0x986ddb5c6b3a76b7, 0xf89629465a75e01d},
+ {0xbe89523386091465, 0xf6bbb397f1135824},
+ {0xee2ba6c0678b597f, 0x746aa07ded582e2d},
+ {0x94db483840b717ef, 0xa8c2a44eb4571cdd},
+ {0xba121a4650e4ddeb, 0x92f34d62616ce414},
+ {0xe896a0d7e51e1566, 0x77b020baf9c81d18},
+ {0x915e2486ef32cd60, 0x0ace1474dc1d122f},
+ {0xb5b5ada8aaff80b8, 0x0d819992132456bb},
+ {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a},
+ {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
+ {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3},
+ {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf},
+ {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c},
+ {0xad4ab7112eb3929d, 0x86c16c98d2c953c7},
+ {0xd89d64d57a607744, 0xe871c7bf077ba8b8},
+ {0x87625f056c7c4a8b, 0x11471cd764ad4973},
+ {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0},
+ {0xd389b47879823479, 0x4aff1d108d4ec2c4},
+ {0x843610cb4bf160cb, 0xcedf722a585139bb},
+ {0xa54394fe1eedb8fe, 0xc2974eb4ee658829},
+ {0xce947a3da6a9273e, 0x733d226229feea33},
+ {0x811ccc668829b887, 0x0806357d5a3f5260},
+ {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8},
+ {0xc9bcff6034c13052, 0xfc89b393dd02f0b6},
+ {0xfc2c3f3841f17c67, 0xbbac2078d443ace3},
+ {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e},
+ {0xc5029163f384a931, 0x0a9e795e65d4df12},
+ {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6},
+ {0x99ea0196163fa42e, 0x504bced1bf8e4e46},
+ {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7},
+ {0xf07da27a82c37088, 0x5d767327bb4e5a4d},
+ {0x964e858c91ba2655, 0x3a6a07f8d510f870},
+ {0xbbe226efb628afea, 0x890489f70a55368c},
+ {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f},
+ {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e},
+ {0xb77ada0617e3bbcb, 0x09ce6ebb40173745},
+ {0xe55990879ddcaabd, 0xcc420a6a101d0516},
+ {0x8f57fa54c2a9eab6, 0x9fa946824a12232e},
+ {0xb32df8e9f3546564, 0x47939822dc96abfa},
+ {0xdff9772470297ebd, 0x59787e2b93bc56f8},
+ {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b},
+ {0xaefae51477a06b03, 0xede622920b6b23f2},
+ {0xdab99e59958885c4, 0xe95fab368e45ecee},
+ {0x88b402f7fd75539b, 0x11dbcb0218ebb415},
+ {0xaae103b5fcd2a881, 0xd652bdc29f26a11a},
+ {0xd59944a37c0752a2, 0x4be76d3346f04960},
+ {0x857fcae62d8493a5, 0x6f70a4400c562ddc},
+ {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953},
+ {0xd097ad07a71f26b2, 0x7e2000a41346a7a8},
+ {0x825ecc24c873782f, 0x8ed400668c0c28c9},
+ {0xa2f67f2dfa90563b, 0x728900802f0f32fb},
+ {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba},
+ {0xfea126b7d78186bc, 0xe2f610c84987bfa9},
+ {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca},
+ {0xc6ede63fa05d3143, 0x91503d1c79720dbc},
+ {0xf8a95fcf88747d94, 0x75a44c6397ce912b},
+ {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb},
+ {0xc24452da229b021b, 0xfbe85badce996169},
+ {0xf2d56790ab41c2a2, 0xfae27299423fb9c4},
+ {0x97c560ba6b0919a5, 0xdccd879fc967d41b},
+ {0xbdb6b8e905cb600f, 0x5400e987bbc1c921},
+ {0xed246723473e3813, 0x290123e9aab23b69},
+ {0x9436c0760c86e30b, 0xf9a0b6720aaf6522},
+ {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
+ {0xe7958cb87392c2c2, 0xb60b1d1230b20e05},
+ {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3},
+ {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4},
+ {0xe2280b6c20dd5232, 0x25c6da63c38de1b1},
+ {0x8d590723948a535f, 0x579c487e5a38ad0f},
+ {0xb0af48ec79ace837, 0x2d835a9df0c6d852},
+ {0xdcdb1b2798182244, 0xf8e431456cf88e66},
+ {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900},
+ {0xac8b2d36eed2dac5, 0xe272467e3d222f40},
+ {0xd7adf884aa879177, 0x5b0ed81dcc6abb10},
+ {0x86ccbb52ea94baea, 0x98e947129fc2b4ea},
+ {0xa87fea27a539e9a5, 0x3f2398d747b36225},
+ {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae},
+ {0x83a3eeeef9153e89, 0x1953cf68300424ad},
+ {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8},
+ {0xcdb02555653131b6, 0x3792f412cb06794e},
+ {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1},
+ {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5},
+ {0xc8de047564d20a8b, 0xf245825a5a445276},
+ {0xfb158592be068d2e, 0xeed6e2f0f0d56713},
+ {0x9ced737bb6c4183d, 0x55464dd69685606c},
+ {0xc428d05aa4751e4c, 0xaa97e14c3c26b887},
+ {0xf53304714d9265df, 0xd53dd99f4b3066a9},
+ {0x993fe2c6d07b7fab, 0xe546a8038efe402a},
+ {0xbf8fdb78849a5f96, 0xde98520472bdd034},
+ {0xef73d256a5c0f77c, 0x963e66858f6d4441},
+ {0x95a8637627989aad, 0xdde7001379a44aa9},
+ {0xbb127c53b17ec159, 0x5560c018580d5d53},
+ {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7},
+ {0x9226712162ab070d, 0xcab3961304ca70e9},
+ {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23},
+ {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b},
+ {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243},
+ {0xb267ed1940f1c61c, 0x55f038b237591ed4},
+ {0xdf01e85f912e37a3, 0x6b6c46dec52f6689},
+ {0x8b61313bbabce2c6, 0x2323ac4b3b3da016},
+ {0xae397d8aa96c1b77, 0xabec975e0a0d081b},
+ {0xd9c7dced53c72255, 0x96e7bd358c904a22},
+ {0x881cea14545c7575, 0x7e50d64177da2e55},
+ {0xaa242499697392d2, 0xdde50bd1d5d0b9ea},
+ {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865},
+ {0x84ec3c97da624ab4, 0xbd5af13bef0b113f},
+ {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f},
+ {0xcfb11ead453994ba, 0x67de18eda5814af3},
+ {0x81ceb32c4b43fcf4, 0x80eacf948770ced8},
+ {0xa2425ff75e14fc31, 0xa1258379a94d028e},
+ {0xcad2f7f5359a3b3e, 0x096ee45813a04331},
+ {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd},
+ {0x9e74d1b791e07e48, 0x775ea264cf55347e},
+ {0xc612062576589dda, 0x95364afe032a819e},
+ {0xf79687aed3eec551, 0x3a83ddbd83f52205},
+ {0x9abe14cd44753b52, 0xc4926a9672793543},
+ {0xc16d9a0095928a27, 0x75b7053c0f178294},
+ {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
+ {0x971da05074da7bee, 0xd3f6fc16ebca5e04},
+ {0xbce5086492111aea, 0x88f4bb1ca6bcf585},
+ {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6},
+ {0x9392ee8e921d5d07, 0x3aff322e62439fd0},
+ {0xb877aa3236a4b449, 0x09befeb9fad487c3},
+ {0xe69594bec44de15b, 0x4c2ebe687989a9b4},
+ {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11},
+ {0xb424dc35095cd80f, 0x538484c19ef38c95},
+ {0xe12e13424bb40e13, 0x2865a5f206b06fba},
+ {0x8cbccc096f5088cb, 0xf93f87b7442e45d4},
+ {0xafebff0bcb24aafe, 0xf78f69a51539d749},
+ {0xdbe6fecebdedd5be, 0xb573440e5a884d1c},
+ {0x89705f4136b4a597, 0x31680a88f8953031},
+ {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e},
+ {0xd6bf94d5e57a42bc, 0x3d32907604691b4d},
+ {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110},
+ {0xa7c5ac471b478423, 0x0fcf80dc33721d54},
+ {0xd1b71758e219652b, 0xd3c36113404ea4a9},
+ {0x83126e978d4fdf3b, 0x645a1cac083126ea},
+ {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4},
+ {0xcccccccccccccccc, 0xcccccccccccccccd},
+ {0x8000000000000000, 0x0000000000000000},
+ {0xa000000000000000, 0x0000000000000000},
+ {0xc800000000000000, 0x0000000000000000},
+ {0xfa00000000000000, 0x0000000000000000},
+ {0x9c40000000000000, 0x0000000000000000},
+ {0xc350000000000000, 0x0000000000000000},
+ {0xf424000000000000, 0x0000000000000000},
+ {0x9896800000000000, 0x0000000000000000},
+ {0xbebc200000000000, 0x0000000000000000},
+ {0xee6b280000000000, 0x0000000000000000},
+ {0x9502f90000000000, 0x0000000000000000},
+ {0xba43b74000000000, 0x0000000000000000},
+ {0xe8d4a51000000000, 0x0000000000000000},
+ {0x9184e72a00000000, 0x0000000000000000},
+ {0xb5e620f480000000, 0x0000000000000000},
+ {0xe35fa931a0000000, 0x0000000000000000},
+ {0x8e1bc9bf04000000, 0x0000000000000000},
+ {0xb1a2bc2ec5000000, 0x0000000000000000},
+ {0xde0b6b3a76400000, 0x0000000000000000},
+ {0x8ac7230489e80000, 0x0000000000000000},
+ {0xad78ebc5ac620000, 0x0000000000000000},
+ {0xd8d726b7177a8000, 0x0000000000000000},
+ {0x878678326eac9000, 0x0000000000000000},
+ {0xa968163f0a57b400, 0x0000000000000000},
+ {0xd3c21bcecceda100, 0x0000000000000000},
+ {0x84595161401484a0, 0x0000000000000000},
+ {0xa56fa5b99019a5c8, 0x0000000000000000},
+ {0xcecb8f27f4200f3a, 0x0000000000000000},
+ {0x813f3978f8940984, 0x4000000000000000},
+ {0xa18f07d736b90be5, 0x5000000000000000},
+ {0xc9f2c9cd04674ede, 0xa400000000000000},
+ {0xfc6f7c4045812296, 0x4d00000000000000},
+ {0x9dc5ada82b70b59d, 0xf020000000000000},
+ {0xc5371912364ce305, 0x6c28000000000000},
+ {0xf684df56c3e01bc6, 0xc732000000000000},
+ {0x9a130b963a6c115c, 0x3c7f400000000000},
+ {0xc097ce7bc90715b3, 0x4b9f100000000000},
+ {0xf0bdc21abb48db20, 0x1e86d40000000000},
+ {0x96769950b50d88f4, 0x1314448000000000},
+ {0xbc143fa4e250eb31, 0x17d955a000000000},
+ {0xeb194f8e1ae525fd, 0x5dcfab0800000000},
+ {0x92efd1b8d0cf37be, 0x5aa1cae500000000},
+ {0xb7abc627050305ad, 0xf14a3d9e40000000},
+ {0xe596b7b0c643c719, 0x6d9ccd05d0000000},
+ {0x8f7e32ce7bea5c6f, 0xe4820023a2000000},
+ {0xb35dbf821ae4f38b, 0xdda2802c8a800000},
+ {0xe0352f62a19e306e, 0xd50b2037ad200000},
+ {0x8c213d9da502de45, 0x4526f422cc340000},
+ {0xaf298d050e4395d6, 0x9670b12b7f410000},
+ {0xdaf3f04651d47b4c, 0x3c0cdd765f114000},
+ {0x88d8762bf324cd0f, 0xa5880a69fb6ac800},
+ {0xab0e93b6efee0053, 0x8eea0d047a457a00},
+ {0xd5d238a4abe98068, 0x72a4904598d6d880},
+ {0x85a36366eb71f041, 0x47a6da2b7f864750},
+ {0xa70c3c40a64e6c51, 0x999090b65f67d924},
+ {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d},
+ {0x82818f1281ed449f, 0xbff8f10e7a8921a4},
+ {0xa321f2d7226895c7, 0xaff72d52192b6a0d},
+ {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490},
+ {0xfee50b7025c36a08, 0x02f236d04753d5b4},
+ {0x9f4f2726179a2245, 0x01d762422c946590},
+ {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5},
+ {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2},
+ {0x9b934c3b330c8577, 0x63cc55f49f88eb2f},
+ {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb},
+ {0xf316271c7fc3908a, 0x8bef464e3945ef7a},
+ {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac},
+ {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317},
+ {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd},
+ {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a},
+ {0xb975d6b6ee39e436, 0xb3e2fd538e122b44},
+ {0xe7d34c64a9c85d44, 0x60dbbca87196b616},
+ {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd},
+ {0xb51d13aea4a488dd, 0x6babab6398bdbe41},
+ {0xe264589a4dcdab14, 0xc696963c7eed2dd1},
+ {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2},
+ {0xb0de65388cc8ada8, 0x3b25a55f43294bcb},
+ {0xdd15fe86affad912, 0x49ef0eb713f39ebe},
+ {0x8a2dbf142dfcc7ab, 0x6e3569326c784337},
+ {0xacb92ed9397bf996, 0x49c2c37f07965404},
+ {0xd7e77a8f87daf7fb, 0xdc33745ec97be906},
+ {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3},
+ {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c},
+ {0xd2d80db02aabd62b, 0xf50a3fa490c30190},
+ {0x83c7088e1aab65db, 0x792667c6da79e0fa},
+ {0xa4b8cab1a1563f52, 0x577001b891185938},
+ {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86},
+ {0x80b05e5ac60b6178, 0x544f8158315b05b4},
+ {0xa0dc75f1778e39d6, 0x696361ae3db1c721},
+ {0xc913936dd571c84c, 0x03bc3a19cd1e38e9},
+ {0xfb5878494ace3a5f, 0x04ab48a04065c723},
+ {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76},
+ {0xc45d1df942711d9a, 0x3ba5d0bd324f8394},
+ {0xf5746577930d6500, 0xca8f44ec7ee36479},
+ {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb},
+ {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e},
+ {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e},
+ {0x95d04aee3b80ece5, 0xbba1f1d158724a12},
+ {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97},
+ {0xea1575143cf97226, 0xf52d09d71a3293bd},
+ {0x924d692ca61be758, 0x593c2626705f9c56},
+ {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c},
+ {0xe498f455c38b997a, 0x0b6dfb9c0f956447},
+ {0x8edf98b59a373fec, 0x4724bd4189bd5eac},
+ {0xb2977ee300c50fe7, 0x58edec91ec2cb657},
+ {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed},
+ {0x8b865b215899f46c, 0xbd79e0d20082ee74},
+ {0xae67f1e9aec07187, 0xecd8590680a3aa11},
+ {0xda01ee641a708de9, 0xe80e6f4820cc9495},
+ {0x884134fe908658b2, 0x3109058d147fdcdd},
+ {0xaa51823e34a7eede, 0xbd4b46f0599fd415},
+ {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a},
+ {0x850fadc09923329e, 0x03e2cf6bc604ddb0},
+ {0xa6539930bf6bff45, 0x84db8346b786151c},
+ {0xcfe87f7cef46ff16, 0xe612641865679a63},
+ {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e},
+ {0xa26da3999aef7749, 0xe3be5e330f38f09d},
+ {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5},
+ {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6},
+ {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa},
+ {0xc646d63501a1511d, 0xb281e1fd541501b8},
+ {0xf7d88bc24209a565, 0x1f225a7ca91a4226},
+ {0x9ae757596946075f, 0x3375788de9b06958},
+ {0xc1a12d2fc3978937, 0x0052d6b1641c83ae},
+ {0xf209787bb47d6b84, 0xc0678c5dbd23a49a},
+ {0x9745eb4d50ce6332, 0xf840b7ba963646e0},
+ {0xbd176620a501fbff, 0xb650e5a93bc3d898},
+ {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe},
+ {0x93ba47c980e98cdf, 0xc66f336c36b10137},
+ {0xb8a8d9bbe123f017, 0xb80b0047445d4184},
+ {0xe6d3102ad96cec1d, 0xa60dc059157491e5},
+ {0x9043ea1ac7e41392, 0x87c89837ad68db2f},
+ {0xb454e4a179dd1877, 0x29babe4598c311fb},
+ {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a},
+ {0x8ce2529e2734bb1d, 0x1899e4a65f58660c},
+ {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f},
+ {0xdc21a1171d42645d, 0x76707543f4fa1f73},
+ {0x899504ae72497eba, 0x6a06494a791c53a8},
+ {0xabfa45da0edbde69, 0x0487db9d17636892},
+ {0xd6f8d7509292d603, 0x45a9d2845d3c42b6},
+ {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2},
+ {0xa7f26836f282b732, 0x8e6cac7768d7141e},
+ {0xd1ef0244af2364ff, 0x3207d795430cd926},
+ {0x8335616aed761f1f, 0x7f44e6bd49e807b8},
+ {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6},
+ {0xcd036837130890a1, 0x36dba887c37a8c0f},
+ {0x802221226be55a64, 0xc2494954da2c9789},
+ {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c},
+ {0xc83553c5c8965d3d, 0x6f92829494e5acc7},
+ {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9},
+ {0x9c69a97284b578d7, 0xff2a760414536efb},
+ {0xc38413cf25e2d70d, 0xfef5138519684aba},
+ {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69},
+ {0x98bf2f79d5993802, 0xef2f773ffbd97a61},
+ {0xbeeefb584aff8603, 0xaafb550ffacfd8fa},
+ {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38},
+ {0x952ab45cfa97a0b2, 0xdd945a747bf26183},
+ {0xba756174393d88df, 0x94f971119aeef9e4},
+ {0xe912b9d1478ceb17, 0x7a37cd5601aab85d},
+ {0x91abb422ccb812ee, 0xac62e055c10ab33a},
+ {0xb616a12b7fe617aa, 0x577b986b314d6009},
+ {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b},
+ {0x8e41ade9fbebc27d, 0x14588f13be847307},
+ {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8},
+ {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb},
+ {0x8aec23d680043bee, 0x25de7bb9480d5854},
+ {0xada72ccc20054ae9, 0xaf561aa79a10ae6a},
+ {0xd910f7ff28069da4, 0x1b2ba1518094da04},
+ {0x87aa9aff79042286, 0x90fb44d2f05d0842},
+ {0xa99541bf57452b28, 0x353a1607ac744a53},
+ {0xd3fa922f2d1675f2, 0x42889b8997915ce8},
+ {0x847c9b5d7c2e09b7, 0x69956135febada11},
+ {0xa59bc234db398c25, 0x43fab9837e699095},
+ {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb},
+ {0x8161afb94b44f57d, 0x1d1be0eebac278f5},
+ {0xa1ba1ba79e1632dc, 0x6462d92a69731732},
+ {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe},
+ {0xfcb2cb35e702af78, 0x5cda735244c3d43e},
+ {0x9defbf01b061adab, 0x3a0888136afa64a7},
+ {0xc56baec21c7a1916, 0x088aaa1845b8fdd0},
+ {0xf6c69a72a3989f5b, 0x8aad549e57273d45},
+ {0x9a3c2087a63f6399, 0x36ac54e2f678864b},
+ {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd},
+ {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5},
+ {0x969eb7c47859e743, 0x9f644ae5a4b1b325},
+ {0xbc4665b596706114, 0x873d5d9f0dde1fee},
+ {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea},
+ {0x9316ff75dd87cbd8, 0x09a7f12442d588f2},
+ {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f},
+ {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa},
+ {0x8fa475791a569d10, 0xf96e017d694487bc},
+ {0xb38d92d760ec4455, 0x37c981dcc395a9ac},
+ {0xe070f78d3927556a, 0x85bbe253f47b1417},
+ {0x8c469ab843b89562, 0x93956d7478ccec8e},
+ {0xaf58416654a6babb, 0x387ac8d1970027b2},
+ {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e},
+ {0x88fcf317f22241e2, 0x441fece3bdf81f03},
+ {0xab3c2fddeeaad25a, 0xd527e81cad7626c3},
+ {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074},
+ {0x85c7056562757456, 0xf6872d5667844e49},
+ {0xa738c6bebb12d16c, 0xb428f8ac016561db},
+ {0xd106f86e69d785c7, 0xe13336d701beba52},
+ {0x82a45b450226b39c, 0xecc0024661173473},
+ {0xa34d721642b06084, 0x27f002d7f95d0190},
+ {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4},
+ {0xff290242c83396ce, 0x7e67047175a15271},
+ {0x9f79a169bd203e41, 0x0f0062c6e984d386},
+ {0xc75809c42c684dd1, 0x52c07b78a3e60868},
+ {0xf92e0c3537826145, 0xa7709a56ccdf8a82},
+ {0x9bbcc7a142b17ccb, 0x88a66076400bb691},
+ {0xc2abf989935ddbfe, 0x6acff893d00ea435},
+ {0xf356f7ebf83552fe, 0x0583f6b8c4124d43},
+ {0x98165af37b2153de, 0xc3727a337a8b704a},
+ {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c},
+ {0xeda2ee1c7064130c, 0x1162def06f79df73},
+ {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8},
+ {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692},
+ {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437},
+ {0x910ab1d4db9914a0, 0x1d9c9892400a22a2},
+ {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b},
+ {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d},
+ {0x8da471a9de737e24, 0x5ceaecfed289e5d2},
+ {0xb10d8e1456105dad, 0x7425a83e872c5f47},
+ {0xdd50f1996b947518, 0xd12f124e28f77719},
+ {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f},
+ {0xace73cbfdc0bfb7b, 0x636cc64d1001550b},
+ {0xd8210befd30efa5a, 0x3c47f7e05401aa4e},
+ {0x8714a775e3e95c78, 0x65acfaec34810a71},
+ {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d},
+ {0xd31045a8341ca07c, 0x1ede48111209a050},
+ {0x83ea2b892091e44d, 0x934aed0aab460432},
+ {0xa4e4b66b68b65d60, 0xf81da84d5617853f},
+ {0xce1de40642e3f4b9, 0x36251260ab9d668e},
+ {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019},
+ {0xa1075a24e4421730, 0xb24cf65b8612f81f},
+ {0xc94930ae1d529cfc, 0xdee033f26797b627},
+ {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1},
+ {0x9d412e0806e88aa5, 0x8e1f289560ee864e},
+ {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2},
+ {0xf5b5d7ec8acb58a2, 0xae10af696774b1db},
+ {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29},
+ {0xbff610b0cc6edd3f, 0x17fd090a58d32af3},
+ {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0},
+ {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e},
+ {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1},
+ {0xea53df5fd18d5513, 0x84c86189216dc5ed},
+ {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4},
+ {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1},
+ {0xe4d5e82392a40515, 0x0fabaf3feaa5334a},
+ {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e},
+ {0xb2c71d5bca9023f8, 0x743e20e9ef511012},
+ {0xdf78e4b2bd342cf6, 0x914da9246b255416},
+ {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e},
+ {0xae9672aba3d0c320, 0xa184ac2473b529b1},
+ {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e},
+ {0x8865899617fb1871, 0x7e2fa67c7a658892},
+ {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7},
+ {0xd51ea6fa85785631, 0x552a74227f3ea565},
+ {0x8533285c936b35de, 0xd53a88958f87275f},
+ {0xa67ff273b8460356, 0x8a892abaf368f137},
+ {0xd01fef10a657842c, 0x2d2b7569b0432d85},
+ {0x8213f56a67f6b29b, 0x9c3b29620e29fc73},
+ {0xa298f2c501f45f42, 0x8349f3ba91b47b8f},
+ {0xcb3f2f7642717713, 0x241c70a936219a73},
+ {0xfe0efb53d30dd4d7, 0xed238cd383aa0110},
+ {0x9ec95d1463e8a506, 0xf4363804324a40aa},
+ {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5},
+ {0xf81aa16fdc1b81da, 0xdd94b7868e94050a},
+ {0x9b10a4e5e9913128, 0xca7cf2b4191c8326},
+ {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0},
+ {0xf24a01a73cf2dccf, 0xbc633b39673c8cec},
+ {0x976e41088617ca01, 0xd5be0503e085d813},
+ {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18},
+ {0xec9c459d51852ba2, 0xddf8e7d60ed1219e},
+ {0x93e1ab8252f33b45, 0xcabb90e5c942b503},
+ {0xb8da1662e7b00a17, 0x3d6a751f3b936243},
+ {0xe7109bfba19c0c9d, 0x0cc512670a783ad4},
+ {0x906a617d450187e2, 0x27fb2b80668b24c5},
+ {0xb484f9dc9641e9da, 0xb1f9f660802dedf6},
+ {0xe1a63853bbd26451, 0x5e7873f8a0396973},
+ {0x8d07e33455637eb2, 0xdb0b487b6423e1e8},
+ {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62},
+ {0xdc5c5301c56b75f7, 0x7641a140cc7810fb},
+ {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d},
+ {0xac2820d9623bf429, 0x546345fa9fbdcd44},
+ {0xd732290fbacaf133, 0xa97c177947ad4095},
+ {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d},
+ {0xa81f301449ee8c70, 0x5c68f256bfff5a74},
+ {0xd226fc195c6a2f8c, 0x73832eec6fff3111},
+ {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab},
+ {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55},
+ {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb},
+ {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3},
+ {0xa0555e361951c366, 0xd7e105bcc332621f},
+ {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7},
+ {0xfa856334878fc150, 0xb14f98f6f0feb951},
+ {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3},
+ {0xc3b8358109e84f07, 0x0a862f80ec4700c8},
+ {0xf4a642e14c6262c8, 0xcd27bb612758c0fa},
+ {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c},
+ {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3},
+ {0xeeea5d5004981478, 0x1858ccfce06cac74},
+ {0x95527a5202df0ccb, 0x0f37801e0c43ebc8},
+ {0xbaa718e68396cffd, 0xd30560258f54e6ba},
+ {0xe950df20247c83fd, 0x47c6b82ef32a2069},
+ {0x91d28b7416cdd27e, 0x4cdc331d57fa5441},
+ {0xb6472e511c81471d, 0xe0133fe4adf8e952},
+ {0xe3d8f9e563a198e5, 0x58180fddd97723a6},
+ {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648},
+ {0xb201833b35d63f73, 0x2cd2cc6551e513da},
+ {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1},
+ {0x8b112e86420f6191, 0xfb04afaf27faf782},
+ {0xadd57a27d29339f6, 0x79c5db9af1f9b563},
+ {0xd94ad8b1c7380874, 0x18375281ae7822bc},
+ {0x87cec76f1c830548, 0x8f2293910d0b15b5},
+ {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22},
+ {0xd433179d9c8cb841, 0x5fa60692a46151eb},
+ {0x849feec281d7f328, 0xdbc7c41ba6bcd333},
+ {0xa5c7ea73224deff3, 0x12b9b522906c0800},
+ {0xcf39e50feae16bef, 0xd768226b34870a00},
+ {0x81842f29f2cce375, 0xe6a1158300d46640},
+ {0xa1e53af46f801c53, 0x60495ae3c1097fd0},
+ {0xca5e89b18b602368, 0x385bb19cb14bdfc4},
+ {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5},
+ {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1},
+ {0xc5a05277621be293, 0xc7098b7305241885},
+ { 0xf70867153aa2db38,
+ 0xb8cbee4fc66d1ea7 }
+#else
+ {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b},
+ {0xce5d73ff402d98e3, 0xfb0a3d212dc81290},
+ {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f},
+ {0x86a8d39ef77164bc, 0xae5dff9c02033198},
+ {0xd98ddaee19068c76, 0x3badd624dd9b0958},
+ {0xafbd2350644eeacf, 0xe5d1929ef90898fb},
+ {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2},
+ {0xe55990879ddcaabd, 0xcc420a6a101d0516},
+ {0xb94470938fa89bce, 0xf808e40e8d5b3e6a},
+ {0x95a8637627989aad, 0xdde7001379a44aa9},
+ {0xf1c90080baf72cb1, 0x5324c68b12dd6339},
+ {0xc350000000000000, 0x0000000000000000},
+ {0x9dc5ada82b70b59d, 0xf020000000000000},
+ {0xfee50b7025c36a08, 0x02f236d04753d5b4},
+ {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86},
+ {0xa6539930bf6bff45, 0x84db8346b786151c},
+ {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2},
+ {0xd910f7ff28069da4, 0x1b2ba1518094da04},
+ {0xaf58416654a6babb, 0x387ac8d1970027b2},
+ {0x8da471a9de737e24, 0x5ceaecfed289e5d2},
+ {0xe4d5e82392a40515, 0x0fabaf3feaa5334a},
+ {0xb8da1662e7b00a17, 0x3d6a751f3b936243},
+ { 0x95527a5202df0ccb,
+ 0x0f37801e0c43ebc8 }
+#endif
+ };
+
+#if FMT_USE_FULL_CACHE_DRAGONBOX
+ return pow10_significands[k - float_info<double>::min_k];
+#else
+ static constexpr const uint64_t powers_of_5_64[] = {
+ 0x0000000000000001, 0x0000000000000005, 0x0000000000000019,
+ 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35,
+ 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1,
+ 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd,
+ 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9,
+ 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5,
+ 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631,
+ 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed,
+ 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9};
+
+ static constexpr const uint32_t pow10_recovery_errors[] = {
+ 0x50001400, 0x54044100, 0x54014555, 0x55954415, 0x54115555, 0x00000001,
+ 0x50000000, 0x00104000, 0x54010004, 0x05004001, 0x55555544, 0x41545555,
+ 0x54040551, 0x15445545, 0x51555514, 0x10000015, 0x00101100, 0x01100015,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04450514, 0x45414110,
+ 0x55555145, 0x50544050, 0x15040155, 0x11054140, 0x50111514, 0x11451454,
+ 0x00400541, 0x00000000, 0x55555450, 0x10056551, 0x10054011, 0x55551014,
+ 0x69514555, 0x05151109, 0x00155555};
+
+ static const int compression_ratio = 27;
+
+ // Compute base index.
+ int cache_index = (k - float_info<double>::min_k) / compression_ratio;
+ int kb = cache_index * compression_ratio + float_info<double>::min_k;
+ int offset = k - kb;
+
+ // Get base cache.
+ uint128_wrapper base_cache = pow10_significands[cache_index];
+ if (offset == 0) return base_cache;
+
+ // Compute the required amount of bit-shift.
+ int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset;
+ FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected");
+
+ // Try to recover the real cache.
+ uint64_t pow5 = powers_of_5_64[offset];
+ uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5);
+ uint128_wrapper middle_low =
+ umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5);
+
+ recovered_cache += middle_low.high();
+
+ uint64_t high_to_middle = recovered_cache.high() << (64 - alpha);
+ uint64_t middle_to_low = recovered_cache.low() << (64 - alpha);
+
+ recovered_cache =
+ uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle,
+ ((middle_low.low() >> alpha) | middle_to_low)};
+
+ if (kb < 0) recovered_cache += 1;
+
+ // Get error.
+ int error_idx = (k - float_info<double>::min_k) / 16;
+ uint32_t error = (pow10_recovery_errors[error_idx] >>
+ ((k - float_info<double>::min_k) % 16) * 2) &
+ 0x3;
+
+ // Add the error back.
+ FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), "");
+ return {recovered_cache.high(), recovered_cache.low() + error};
+#endif
+ }
+
+ static carrier_uint compute_mul(carrier_uint u,
+ const cache_entry_type& cache) FMT_NOEXCEPT {
+ return umul192_upper64(u, cache);
+ }
+
+ static uint32_t compute_delta(cache_entry_type const& cache,
+ int beta_minus_1) FMT_NOEXCEPT {
+ return static_cast<uint32_t>(cache.high() >> (64 - 1 - beta_minus_1));
+ }
+
+ static bool compute_mul_parity(carrier_uint two_f,
+ const cache_entry_type& cache,
+ int beta_minus_1) FMT_NOEXCEPT {
+ FMT_ASSERT(beta_minus_1 >= 1, "");
+ FMT_ASSERT(beta_minus_1 < 64, "");
+
+ return ((umul192_middle64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0;
+ }
+
+ static carrier_uint compute_left_endpoint_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return (cache.high() -
+ (cache.high() >> (float_info<double>::significand_bits + 2))) >>
+ (64 - float_info<double>::significand_bits - 1 - beta_minus_1);
+ }
+
+ static carrier_uint compute_right_endpoint_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return (cache.high() +
+ (cache.high() >> (float_info<double>::significand_bits + 1))) >>
+ (64 - float_info<double>::significand_bits - 1 - beta_minus_1);
+ }
+
+ static carrier_uint compute_round_up_for_shorter_interval_case(
+ const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT {
+ return ((cache.high() >>
+ (64 - float_info<double>::significand_bits - 2 - beta_minus_1)) +
+ 1) /
+ 2;
+ }
+};
+
+// Various integer checks
+template <class T>
+bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT {
+ return exponent >=
+ float_info<
+ T>::case_shorter_interval_left_endpoint_lower_threshold &&
+ exponent <=
+ float_info<T>::case_shorter_interval_left_endpoint_upper_threshold;
+}
+template <class T>
+bool is_endpoint_integer(typename float_info<T>::carrier_uint two_f,
+ int exponent, int minus_k) FMT_NOEXCEPT {
+ if (exponent < float_info<T>::case_fc_pm_half_lower_threshold) return false;
+ // For k >= 0.
+ if (exponent <= float_info<T>::case_fc_pm_half_upper_threshold) return true;
+ // For k < 0.
+ if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false;
+ return divisible_by_power_of_5(two_f, minus_k);
+}
+
+template <class T>
+bool is_center_integer(typename float_info<T>::carrier_uint two_f, int exponent,
+ int minus_k) FMT_NOEXCEPT {
+ // Exponent for 5 is negative.
+ if (exponent > float_info<T>::divisibility_check_by_5_threshold) return false;
+ if (exponent > float_info<T>::case_fc_upper_threshold)
+ return divisible_by_power_of_5(two_f, minus_k);
+ // Both exponents are nonnegative.
+ if (exponent >= float_info<T>::case_fc_lower_threshold) return true;
+ // Exponent for 2 is negative.
+ return divisible_by_power_of_2(two_f, minus_k - exponent + 1);
+}
+
+// Remove trailing zeros from n and return the number of zeros removed (float)
+FMT_INLINE int remove_trailing_zeros(uint32_t& n) FMT_NOEXCEPT {
+#ifdef FMT_BUILTIN_CTZ
+ int t = FMT_BUILTIN_CTZ(n);
+#else
+ int t = ctz(n);
+#endif
+ if (t > float_info<float>::max_trailing_zeros)
+ t = float_info<float>::max_trailing_zeros;
+
+ const uint32_t mod_inv1 = 0xcccccccd;
+ const uint32_t max_quotient1 = 0x33333333;
+ const uint32_t mod_inv2 = 0xc28f5c29;
+ const uint32_t max_quotient2 = 0x0a3d70a3;
+
+ int s = 0;
+ for (; s < t - 1; s += 2) {
+ if (n * mod_inv2 > max_quotient2) break;
+ n *= mod_inv2;
+ }
+ if (s < t && n * mod_inv1 <= max_quotient1) {
+ n *= mod_inv1;
+ ++s;
+ }
+ n >>= s;
+ return s;
+}
+
+// Removes trailing zeros and returns the number of zeros removed (double)
+FMT_INLINE int remove_trailing_zeros(uint64_t& n) FMT_NOEXCEPT {
+#ifdef FMT_BUILTIN_CTZLL
+ int t = FMT_BUILTIN_CTZLL(n);
+#else
+ int t = ctzll(n);
+#endif
+ if (t > float_info<double>::max_trailing_zeros)
+ t = float_info<double>::max_trailing_zeros;
+ // Divide by 10^8 and reduce to 32-bits
+ // Since ret_value.significand <= (2^64 - 1) / 1000 < 10^17,
+ // both of the quotient and the r should fit in 32-bits
+
+ const uint32_t mod_inv1 = 0xcccccccd;
+ const uint32_t max_quotient1 = 0x33333333;
+ const uint64_t mod_inv8 = 0xc767074b22e90e21;
+ const uint64_t max_quotient8 = 0x00002af31dc46118;
+
+ // If the number is divisible by 1'0000'0000, work with the quotient
+ if (t >= 8) {
+ auto quotient_candidate = n * mod_inv8;
+
+ if (quotient_candidate <= max_quotient8) {
+ auto quotient = static_cast<uint32_t>(quotient_candidate >> 8);
+
+ int s = 8;
+ for (; s < t; ++s) {
+ if (quotient * mod_inv1 > max_quotient1) break;
+ quotient *= mod_inv1;
+ }
+ quotient >>= (s - 8);
+ n = quotient;
+ return s;
+ }
+ }
+
+ // Otherwise, work with the remainder
+ auto quotient = static_cast<uint32_t>(n / 100000000);
+ auto remainder = static_cast<uint32_t>(n - 100000000 * quotient);
+
+ if (t == 0 || remainder * mod_inv1 > max_quotient1) {
+ return 0;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 1 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 1) + quotient * 10000000ull;
+ return 1;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 2 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 2) + quotient * 1000000ull;
+ return 2;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 3 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 3) + quotient * 100000ull;
+ return 3;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 4 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 4) + quotient * 10000ull;
+ return 4;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 5 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 5) + quotient * 1000ull;
+ return 5;
+ }
+ remainder *= mod_inv1;
+
+ if (t == 6 || remainder * mod_inv1 > max_quotient1) {
+ n = (remainder >> 6) + quotient * 100ull;
+ return 6;
+ }
+ remainder *= mod_inv1;
+
+ n = (remainder >> 7) + quotient * 10ull;
+ return 7;
+}
+
+// The main algorithm for shorter interval case
+template <class T>
+FMT_INLINE decimal_fp<T> shorter_interval_case(int exponent) FMT_NOEXCEPT {
+ decimal_fp<T> ret_value;
+ // Compute k and beta
+ const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent);
+ const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k);
+
+ // Compute xi and zi
+ using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
+ const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
+
+ auto xi = cache_accessor<T>::compute_left_endpoint_for_shorter_interval_case(
+ cache, beta_minus_1);
+ auto zi = cache_accessor<T>::compute_right_endpoint_for_shorter_interval_case(
+ cache, beta_minus_1);
+
+ // If the left endpoint is not an integer, increase it
+ if (!is_left_endpoint_integer_shorter_interval<T>(exponent)) ++xi;
+
+ // Try bigger divisor
+ ret_value.significand = zi / 10;
+
+ // If succeed, remove trailing zeros if necessary and return
+ if (ret_value.significand * 10 >= xi) {
+ ret_value.exponent = minus_k + 1;
+ ret_value.exponent += remove_trailing_zeros(ret_value.significand);
+ return ret_value;
+ }
+
+ // Otherwise, compute the round-up of y
+ ret_value.significand =
+ cache_accessor<T>::compute_round_up_for_shorter_interval_case(
+ cache, beta_minus_1);
+ ret_value.exponent = minus_k;
+
+ // When tie occurs, choose one of them according to the rule
+ if (exponent >= float_info<T>::shorter_interval_tie_lower_threshold &&
+ exponent <= float_info<T>::shorter_interval_tie_upper_threshold) {
+ ret_value.significand = ret_value.significand % 2 == 0
+ ? ret_value.significand
+ : ret_value.significand - 1;
+ } else if (ret_value.significand < xi) {
+ ++ret_value.significand;
+ }
+ return ret_value;
+}
+
+template <typename T> decimal_fp<T> to_decimal(T x) FMT_NOEXCEPT {
+ // Step 1: integer promotion & Schubfach multiplier calculation.
+
+ using carrier_uint = typename float_info<T>::carrier_uint;
+ using cache_entry_type = typename cache_accessor<T>::cache_entry_type;
+ auto br = bit_cast<carrier_uint>(x);
+
+ // Extract significand bits and exponent bits.
+ const carrier_uint significand_mask =
+ (static_cast<carrier_uint>(1) << float_info<T>::significand_bits) - 1;
+ carrier_uint significand = (br & significand_mask);
+ int exponent = static_cast<int>((br & exponent_mask<T>()) >>
+ float_info<T>::significand_bits);
+
+ if (exponent != 0) { // Check if normal.
+ exponent += float_info<T>::exponent_bias - float_info<T>::significand_bits;
+
+ // Shorter interval case; proceed like Schubfach.
+ if (significand == 0) return shorter_interval_case<T>(exponent);
+
+ significand |=
+ (static_cast<carrier_uint>(1) << float_info<T>::significand_bits);
+ } else {
+ // Subnormal case; the interval is always regular.
+ if (significand == 0) return {0, 0};
+ exponent = float_info<T>::min_exponent - float_info<T>::significand_bits;
+ }
+
+ const bool include_left_endpoint = (significand % 2 == 0);
+ const bool include_right_endpoint = include_left_endpoint;
+
+ // Compute k and beta.
+ const int minus_k = floor_log10_pow2(exponent) - float_info<T>::kappa;
+ const cache_entry_type cache = cache_accessor<T>::get_cached_power(-minus_k);
+ const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k);
+
+ // Compute zi and deltai
+ // 10^kappa <= deltai < 10^(kappa + 1)
+ const uint32_t deltai = cache_accessor<T>::compute_delta(cache, beta_minus_1);
+ const carrier_uint two_fc = significand << 1;
+ const carrier_uint two_fr = two_fc | 1;
+ const carrier_uint zi =
+ cache_accessor<T>::compute_mul(two_fr << beta_minus_1, cache);
+
+ // Step 2: Try larger divisor; remove trailing zeros if necessary
+
+ // Using an upper bound on zi, we might be able to optimize the division
+ // better than the compiler; we are computing zi / big_divisor here
+ decimal_fp<T> ret_value;
+ ret_value.significand = divide_by_10_to_kappa_plus_1(zi);
+ uint32_t r = static_cast<uint32_t>(zi - float_info<T>::big_divisor *
+ ret_value.significand);
+
+ if (r > deltai) {
+ goto small_divisor_case_label;
+ } else if (r < deltai) {
+ // Exclude the right endpoint if necessary
+ if (r == 0 && !include_right_endpoint &&
+ is_endpoint_integer<T>(two_fr, exponent, minus_k)) {
+ --ret_value.significand;
+ r = float_info<T>::big_divisor;
+ goto small_divisor_case_label;
+ }
+ } else {
+ // r == deltai; compare fractional parts
+ // Check conditions in the order different from the paper
+ // to take advantage of short-circuiting
+ const carrier_uint two_fl = two_fc - 1;
+ if ((!include_left_endpoint ||
+ !is_endpoint_integer<T>(two_fl, exponent, minus_k)) &&
+ !cache_accessor<T>::compute_mul_parity(two_fl, cache, beta_minus_1)) {
+ goto small_divisor_case_label;
+ }
+ }
+ ret_value.exponent = minus_k + float_info<T>::kappa + 1;
+
+ // We may need to remove trailing zeros
+ ret_value.exponent += remove_trailing_zeros(ret_value.significand);
+ return ret_value;
+
+ // Step 3: Find the significand with the smaller divisor
+
+small_divisor_case_label:
+ ret_value.significand *= 10;
+ ret_value.exponent = minus_k + float_info<T>::kappa;
+
+ const uint32_t mask = (1u << float_info<T>::kappa) - 1;
+ auto dist = r - (deltai / 2) + (float_info<T>::small_divisor / 2);
+
+ // Is dist divisible by 2^kappa?
+ if ((dist & mask) == 0) {
+ const bool approx_y_parity =
+ ((dist ^ (float_info<T>::small_divisor / 2)) & 1) != 0;
+ dist >>= float_info<T>::kappa;
+
+ // Is dist divisible by 5^kappa?
+ if (check_divisibility_and_divide_by_pow5<float_info<T>::kappa>(dist)) {
+ ret_value.significand += dist;
+
+ // Check z^(f) >= epsilon^(f)
+ // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1,
+ // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f)
+ // Since there are only 2 possibilities, we only need to care about the
+ // parity. Also, zi and r should have the same parity since the divisor
+ // is an even number
+ if (cache_accessor<T>::compute_mul_parity(two_fc, cache, beta_minus_1) !=
+ approx_y_parity) {
+ --ret_value.significand;
+ } else {
+ // If z^(f) >= epsilon^(f), we might have a tie
+ // when z^(f) == epsilon^(f), or equivalently, when y is an integer
+ if (is_center_integer<T>(two_fc, exponent, minus_k)) {
+ ret_value.significand = ret_value.significand % 2 == 0
+ ? ret_value.significand
+ : ret_value.significand - 1;
+ }
+ }
+ }
+ // Is dist not divisible by 5^kappa?
+ else {
+ ret_value.significand += dist;
+ }
+ }
+ // Is dist not divisible by 2^kappa?
+ else {
+ // Since we know dist is small, we might be able to optimize the division
+ // better than the compiler; we are computing dist / small_divisor here
+ ret_value.significand +=
+ small_division_by_pow10<float_info<T>::kappa>(dist);
+ }
+ return ret_value;
+}
+} // namespace dragonbox
+
+// Formats a floating-point number using a variation of the Fixed-Precision
+// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White:
+// https://fmt.dev/papers/p372-steele.pdf.
+FMT_CONSTEXPR20 inline void format_dragon(fp value, bool is_predecessor_closer,
+ int num_digits, buffer<char>& buf,
+ int& exp10) {
+ bigint numerator; // 2 * R in (FPP)^2.
+ bigint denominator; // 2 * S in (FPP)^2.
+ // lower and upper are differences between value and corresponding boundaries.
+ bigint lower; // (M^- in (FPP)^2).
+ bigint upper_store; // upper's value if different from lower.
+ bigint* upper = nullptr; // (M^+ in (FPP)^2).
+ // Shift numerator and denominator by an extra bit or two (if lower boundary
+ // is closer) to make lower and upper integers. This eliminates multiplication
+ // by 2 during later computations.
+ int shift = is_predecessor_closer ? 2 : 1;
+ uint64_t significand = value.f << shift;
+ if (value.e >= 0) {
+ numerator.assign(significand);
+ numerator <<= value.e;
+ lower.assign(1);
+ lower <<= value.e;
+ if (shift != 1) {
+ upper_store.assign(1);
+ upper_store <<= value.e + 1;
+ upper = &upper_store;
+ }
+ denominator.assign_pow10(exp10);
+ denominator <<= shift;
+ } else if (exp10 < 0) {
+ numerator.assign_pow10(-exp10);
+ lower.assign(numerator);
+ if (shift != 1) {
+ upper_store.assign(numerator);
+ upper_store <<= 1;
+ upper = &upper_store;
+ }
+ numerator *= significand;
+ denominator.assign(1);
+ denominator <<= shift - value.e;
+ } else {
+ numerator.assign(significand);
+ denominator.assign_pow10(exp10);
+ denominator <<= shift - value.e;
+ lower.assign(1);
+ if (shift != 1) {
+ upper_store.assign(1ULL << 1);
+ upper = &upper_store;
+ }
+ }
+ // Invariant: value == (numerator / denominator) * pow(10, exp10).
+ if (num_digits < 0) {
+ // Generate the shortest representation.
+ if (!upper) upper = &lower;
+ bool even = (value.f & 1) == 0;
+ num_digits = 0;
+ char* data = buf.data();
+ for (;;) {
+ int digit = numerator.divmod_assign(denominator);
+ bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower.
+ // numerator + upper >[=] pow10:
+ bool high = add_compare(numerator, *upper, denominator) + even > 0;
+ data[num_digits++] = static_cast<char>('0' + digit);
+ if (low || high) {
+ if (!low) {
+ ++data[num_digits - 1];
+ } else if (high) {
+ int result = add_compare(numerator, numerator, denominator);
+ // Round half to even.
+ if (result > 0 || (result == 0 && (digit % 2) != 0))
+ ++data[num_digits - 1];
+ }
+ buf.try_resize(to_unsigned(num_digits));
+ exp10 -= num_digits - 1;
+ return;
+ }
+ numerator *= 10;
+ lower *= 10;
+ if (upper != &lower) *upper *= 10;
+ }
+ }
+ // Generate the given number of digits.
+ exp10 -= num_digits - 1;
+ if (num_digits == 0) {
+ denominator *= 10;
+ auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0';
+ buf.push_back(digit);
+ return;
+ }
+ buf.try_resize(to_unsigned(num_digits));
+ for (int i = 0; i < num_digits - 1; ++i) {
+ int digit = numerator.divmod_assign(denominator);
+ buf[i] = static_cast<char>('0' + digit);
+ numerator *= 10;
+ }
+ int digit = numerator.divmod_assign(denominator);
+ auto result = add_compare(numerator, numerator, denominator);
+ if (result > 0 || (result == 0 && (digit % 2) != 0)) {
+ if (digit == 9) {
+ const auto overflow = '0' + 10;
+ buf[num_digits - 1] = overflow;
+ // Propagate the carry.
+ for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) {
+ buf[i] = '0';
+ ++buf[i - 1];
+ }
+ if (buf[0] == overflow) {
+ buf[0] = '1';
+ ++exp10;
+ }
+ return;
+ }
+ ++digit;
+ }
+ buf[num_digits - 1] = static_cast<char>('0' + digit);
+}
+
+template <typename Float>
+FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision,
+ float_specs specs,
+ buffer<char>& buf) {
+ // float is passed as double to reduce the number of instantiations.
+ static_assert(!std::is_same<Float, float>::value, "");
+ FMT_ASSERT(value >= 0, "value is negative");
+
+ const bool fixed = specs.format == float_format::fixed;
+ if (value <= 0) { // <= instead of == to silence a warning.
+ if (precision <= 0 || !fixed) {
+ buf.push_back('0');
+ return 0;
+ }
+ buf.try_resize(to_unsigned(precision));
+ fill_n(buf.data(), precision, '0');
+ return -precision;
+ }
+
+ if (specs.fallback) return snprintf_float(value, precision, specs, buf);
+
+ if (!is_constant_evaluated() && precision < 0) {
+ // Use Dragonbox for the shortest format.
+ if (specs.binary32) {
+ auto dec = dragonbox::to_decimal(static_cast<float>(value));
+ write<char>(buffer_appender<char>(buf), dec.significand);
+ return dec.exponent;
+ }
+ auto dec = dragonbox::to_decimal(static_cast<double>(value));
+ write<char>(buffer_appender<char>(buf), dec.significand);
+ return dec.exponent;
+ }
+
+ int exp = 0;
+ bool use_dragon = true;
+ if (is_fast_float<Float>()) {
+ // Use Grisu + Dragon4 for the given precision:
+ // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
+ const int min_exp = -60; // alpha in Grisu.
+ int cached_exp10 = 0; // K in Grisu.
+ fp normalized = normalize(fp(value));
+ const auto cached_pow = get_cached_power(
+ min_exp - (normalized.e + fp::num_significand_bits), cached_exp10);
+ normalized = normalized * cached_pow;
+ gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
+ if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error &&
+ !is_constant_evaluated()) {
+ exp += handler.exp10;
+ buf.try_resize(to_unsigned(handler.size));
+ use_dragon = false;
+ } else {
+ exp += handler.size - cached_exp10 - 1;
+ precision = handler.precision;
+ }
+ }
+ if (use_dragon) {
+ auto f = fp();
+ bool is_predecessor_closer =
+ specs.binary32 ? f.assign(static_cast<float>(value)) : f.assign(value);
+ // Limit precision to the maximum possible number of significant digits in
+ // an IEEE754 double because we don't need to generate zeros.
+ const int max_double_digits = 767;
+ if (precision > max_double_digits) precision = max_double_digits;
+ format_dragon(f, is_predecessor_closer, precision, buf, exp);
+ }
+ if (!fixed && !specs.showpoint) {
+ // Remove trailing zeros.
+ auto num_digits = buf.size();
+ while (num_digits > 0 && buf[num_digits - 1] == '0') {
+ --num_digits;
+ ++exp;
+ }
+ buf.try_resize(num_digits);
+ }
+ return exp;
+}
+
+template <typename T>
+int snprintf_float(T value, int precision, float_specs specs,
+ buffer<char>& buf) {
+ // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail.
+ FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer");
+ static_assert(!std::is_same<T, float>::value, "");
+
+ // Subtract 1 to account for the difference in precision since we use %e for
+ // both general and exponent format.
+ if (specs.format == float_format::general ||
+ specs.format == float_format::exp)
+ precision = (precision >= 0 ? precision : 6) - 1;
+
+ // Build the format string.
+ enum { max_format_size = 7 }; // The longest format is "%#.*Le".
+ char format[max_format_size];
+ char* format_ptr = format;
+ *format_ptr++ = '%';
+ if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#';
+ if (precision >= 0) {
+ *format_ptr++ = '.';
+ *format_ptr++ = '*';
+ }
+ if (std::is_same<T, long double>()) *format_ptr++ = 'L';
+ *format_ptr++ = specs.format != float_format::hex
+ ? (specs.format == float_format::fixed ? 'f' : 'e')
+ : (specs.upper ? 'A' : 'a');
+ *format_ptr = '\0';
+
+ // Format using snprintf.
+ auto offset = buf.size();
+ for (;;) {
+ auto begin = buf.data() + offset;
+ auto capacity = buf.capacity() - offset;
+#ifdef FMT_FUZZ
+ if (precision > 100000)
+ throw std::runtime_error(
+ "fuzz mode - avoid large allocation inside snprintf");
+#endif
+ // Suppress the warning about a nonliteral format string.
+ // Cannot use auto because of a bug in MinGW (#1532).
+ int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
+ int result = precision >= 0
+ ? snprintf_ptr(begin, capacity, format, precision, value)
+ : snprintf_ptr(begin, capacity, format, value);
+ if (result < 0) {
+ // The buffer will grow exponentially.
+ buf.try_reserve(buf.capacity() + 1);
+ continue;
+ }
+ auto size = to_unsigned(result);
+ // Size equal to capacity means that the last character was truncated.
+ if (size >= capacity) {
+ buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'.
+ continue;
+ }
+ auto is_digit = [](char c) { return c >= '0' && c <= '9'; };
+ if (specs.format == float_format::fixed) {
+ if (precision == 0) {
+ buf.try_resize(size);
+ return 0;
+ }
+ // Find and remove the decimal point.
+ auto end = begin + size, p = end;
+ do {
+ --p;
+ } while (is_digit(*p));
+ int fraction_size = static_cast<int>(end - p - 1);
+ std::memmove(p, p + 1, to_unsigned(fraction_size));
+ buf.try_resize(size - 1);
+ return -fraction_size;
+ }
+ if (specs.format == float_format::hex) {
+ buf.try_resize(size + offset);
+ return 0;
+ }
+ // Find and parse the exponent.
+ auto end = begin + size, exp_pos = end;
+ do {
+ --exp_pos;
+ } while (*exp_pos != 'e');
+ char sign = exp_pos[1];
+ FMT_ASSERT(sign == '+' || sign == '-', "");
+ int exp = 0;
+ auto p = exp_pos + 2; // Skip 'e' and sign.
+ do {
+ FMT_ASSERT(is_digit(*p), "");
+ exp = exp * 10 + (*p++ - '0');
+ } while (p != end);
+ if (sign == '-') exp = -exp;
+ int fraction_size = 0;
+ if (exp_pos != begin + 1) {
+ // Remove trailing zeros.
+ auto fraction_end = exp_pos - 1;
+ while (*fraction_end == '0') --fraction_end;
+ // Move the fractional part left to get rid of the decimal point.
+ fraction_size = static_cast<int>(fraction_end - begin - 1);
+ std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size));
+ }
+ buf.try_resize(to_unsigned(fraction_size) + offset + 1);
+ return exp - fraction_size;
+ }
+}
+} // namespace detail
+
+template <> struct formatter<detail::bigint> {
+ FMT_CONSTEXPR format_parse_context::iterator parse(
+ format_parse_context& ctx) {
+ return ctx.begin();
+ }
+
+ format_context::iterator format(const detail::bigint& n,
+ format_context& ctx) {
+ auto out = ctx.out();
+ bool first = true;
+ for (auto i = n.bigits_.size(); i > 0; --i) {
+ auto value = n.bigits_[i - 1u];
+ if (first) {
+ out = format_to(out, FMT_STRING("{:x}"), value);
+ first = false;
+ continue;
+ }
+ out = format_to(out, FMT_STRING("{:08x}"), value);
+ }
+ if (n.exp_ > 0)
+ out = format_to(out, FMT_STRING("p{}"),
+ n.exp_ * detail::bigint::bigit_bits);
+ return out;
+ }
+};
+
+FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
+ for_each_codepoint(s, [this](uint32_t cp, string_view) {
+ if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8"));
+ if (cp <= 0xFFFF) {
+ buffer_.push_back(static_cast<wchar_t>(cp));
+ } else {
+ cp -= 0x10000;
+ buffer_.push_back(static_cast<wchar_t>(0xD800 + (cp >> 10)));
+ buffer_.push_back(static_cast<wchar_t>(0xDC00 + (cp & 0x3FF)));
+ }
+ return true;
+ });
+ buffer_.push_back(0);
+}
+
+FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
+ const char* message) FMT_NOEXCEPT {
+ FMT_TRY {
+ auto ec = std::error_code(error_code, std::generic_category());
+ write(std::back_inserter(out), std::system_error(ec, message).what());
+ return;
+ }
+ FMT_CATCH(...) {}
+ format_error_code(out, error_code, message);
+}
+
+FMT_FUNC void report_system_error(int error_code,
+ const char* message) FMT_NOEXCEPT {
+ report_error(format_system_error, error_code, message);
+}
+
+// DEPRECATED!
+// This function is defined here and not inline for ABI compatiblity.
+FMT_FUNC void detail::error_handler::on_error(const char* message) {
+ throw_format_error(message);
+}
+
+FMT_FUNC std::string vformat(string_view fmt, format_args args) {
+ // Don't optimize the "{}" case to keep the binary size small and because it
+ // can be better optimized in fmt::format anyway.
+ auto buffer = memory_buffer();
+ detail::vformat_to(buffer, fmt, args);
+ return to_string(buffer);
+}
+
+#ifdef _WIN32
+namespace detail {
+using dword = conditional_t<sizeof(long) == 4, unsigned long, unsigned>;
+extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( //
+ void*, const void*, dword, dword*, void*);
+} // namespace detail
+#endif
+
+namespace detail {
+FMT_FUNC void print(std::FILE* f, string_view text) {
+#ifdef _WIN32
+ auto fd = _fileno(f);
+ if (_isatty(fd)) {
+ detail::utf8_to_utf16 u16(string_view(text.data(), text.size()));
+ auto written = detail::dword();
+ if (detail::WriteConsoleW(reinterpret_cast<void*>(_get_osfhandle(fd)),
+ u16.c_str(), static_cast<uint32_t>(u16.size()),
+ &written, nullptr)) {
+ return;
+ }
+ // Fallback to fwrite on failure. It can happen if the output has been
+ // redirected to NUL.
+ }
+#endif
+ detail::fwrite_fully(text.data(), 1, text.size(), f);
+}
+} // namespace detail
+
+FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
+ memory_buffer buffer;
+ detail::vformat_to(buffer, format_str, args);
+ detail::print(f, {buffer.data(), buffer.size()});
+}
+
+#ifdef _WIN32
+// Print assuming legacy (non-Unicode) encoding.
+FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
+ format_args args) {
+ memory_buffer buffer;
+ detail::vformat_to(buffer, format_str,
+ basic_format_args<buffer_context<char>>(args));
+ fwrite_fully(buffer.data(), 1, buffer.size(), f);
+}
+#endif
+
+FMT_FUNC void vprint(string_view format_str, format_args args) {
+ vprint(stdout, format_str, args);
+}
+
+FMT_END_NAMESPACE
+
+#endif // FMT_FORMAT_INL_H_
diff --git a/extern/fmtlib/include/fmt/format.h b/extern/fmtlib/include/fmt/format.h
new file mode 100644
index 00000000000..ee69651ca54
--- /dev/null
+++ b/extern/fmtlib/include/fmt/format.h
@@ -0,0 +1,3104 @@
+/*
+ Formatting library for C++
+
+ Copyright (c) 2012 - present, Victor Zverovich
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ --- Optional exception to the license ---
+
+ As an exception, if, as a result of your compiling your source code, portions
+ of this Software are embedded into a machine-executable object form of such
+ source code, you may redistribute such embedded portions in such object form
+ without including the above copyright and permission notices.
+ */
+
+#ifndef FMT_FORMAT_H_
+#define FMT_FORMAT_H_
+
+#include <cmath> // std::signbit
+#include <cstdint> // uint32_t
+#include <limits> // std::numeric_limits
+#include <memory> // std::uninitialized_copy
+#include <stdexcept> // std::runtime_error
+#include <system_error> // std::system_error
+#include <utility> // std::swap
+
+#ifdef __cpp_lib_bit_cast
+# include <bit> // std::bitcast
+#endif
+
+#include "core.h"
+
+#if FMT_GCC_VERSION
+# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden")))
+#else
+# define FMT_GCC_VISIBILITY_HIDDEN
+#endif
+
+#ifdef __NVCC__
+# define FMT_CUDA_VERSION (__CUDACC_VER_MAJOR__ * 100 + __CUDACC_VER_MINOR__)
+#else
+# define FMT_CUDA_VERSION 0
+#endif
+
+#ifdef __has_builtin
+# define FMT_HAS_BUILTIN(x) __has_builtin(x)
+#else
+# define FMT_HAS_BUILTIN(x) 0
+#endif
+
+#if FMT_GCC_VERSION || FMT_CLANG_VERSION
+# define FMT_NOINLINE __attribute__((noinline))
+#else
+# define FMT_NOINLINE
+#endif
+
+#if FMT_MSC_VER
+# define FMT_MSC_DEFAULT = default
+#else
+# define FMT_MSC_DEFAULT
+#endif
+
+#ifndef FMT_THROW
+# if FMT_EXCEPTIONS
+# if FMT_MSC_VER || FMT_NVCC
+FMT_BEGIN_NAMESPACE
+namespace detail {
+template <typename Exception> inline void do_throw(const Exception& x) {
+ // Silence unreachable code warnings in MSVC and NVCC because these
+ // are nearly impossible to fix in a generic code.
+ volatile bool b = true;
+ if (b) throw x;
+}
+} // namespace detail
+FMT_END_NAMESPACE
+# define FMT_THROW(x) detail::do_throw(x)
+# else
+# define FMT_THROW(x) throw x
+# endif
+# else
+# define FMT_THROW(x) \
+ do { \
+ FMT_ASSERT(false, (x).what()); \
+ } while (false)
+# endif
+#endif
+
+#if FMT_EXCEPTIONS
+# define FMT_TRY try
+# define FMT_CATCH(x) catch (x)
+#else
+# define FMT_TRY if (true)
+# define FMT_CATCH(x) if (false)
+#endif
+
+#ifndef FMT_MAYBE_UNUSED
+# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
+# define FMT_MAYBE_UNUSED [[maybe_unused]]
+# else
+# define FMT_MAYBE_UNUSED
+# endif
+#endif
+
+// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers.
+#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC
+# define FMT_DEPRECATED_ALIAS
+#else
+# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED
+#endif
+
+#ifndef FMT_USE_USER_DEFINED_LITERALS
+// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
+# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
+ FMT_MSC_VER >= 1900) && \
+ (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
+# define FMT_USE_USER_DEFINED_LITERALS 1
+# else
+# define FMT_USE_USER_DEFINED_LITERALS 0
+# endif
+#endif
+
+// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of
+// integer formatter template instantiations to just one by only using the
+// largest integer type. This results in a reduction in binary size but will
+// cause a decrease in integer formatting performance.
+#if !defined(FMT_REDUCE_INT_INSTANTIATIONS)
+# define FMT_REDUCE_INT_INSTANTIATIONS 0
+#endif
+
+// __builtin_clz is broken in clang with Microsoft CodeGen:
+// https://github.com/fmtlib/fmt/issues/519.
+#if !FMT_MSC_VER
+# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION
+# define FMT_BUILTIN_CLZ(n) __builtin_clz(n)
+# endif
+# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
+# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n)
+# endif
+#endif
+
+// __builtin_ctz is broken in Intel Compiler Classic on Windows:
+// https://github.com/fmtlib/fmt/issues/2510.
+#ifndef __ICL
+# if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION
+# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n)
+# endif
+# if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || FMT_ICC_VERSION
+# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n)
+# endif
+#endif
+
+#if FMT_MSC_VER
+# include <intrin.h> // _BitScanReverse[64], _BitScanForward[64], _umul128
+#endif
+
+// Some compilers masquerade as both MSVC and GCC-likes or otherwise support
+// __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the
+// MSVC intrinsics if the clz and clzll builtins are not available.
+#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL)
+FMT_BEGIN_NAMESPACE
+namespace detail {
+// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
+# if !defined(__clang__)
+# pragma intrinsic(_BitScanForward)
+# pragma intrinsic(_BitScanReverse)
+# if defined(_WIN64)
+# pragma intrinsic(_BitScanForward64)
+# pragma intrinsic(_BitScanReverse64)
+# endif
+# endif
+
+inline auto clz(uint32_t x) -> int {
+ unsigned long r = 0;
+ _BitScanReverse(&r, x);
+ FMT_ASSERT(x != 0, "");
+ // Static analysis complains about using uninitialized data
+ // "r", but the only way that can happen is if "x" is 0,
+ // which the callers guarantee to not happen.
+ FMT_MSC_WARNING(suppress : 6102)
+ return 31 ^ static_cast<int>(r);
+}
+# define FMT_BUILTIN_CLZ(n) detail::clz(n)
+
+inline auto clzll(uint64_t x) -> int {
+ unsigned long r = 0;
+# ifdef _WIN64
+ _BitScanReverse64(&r, x);
+# else
+ // Scan the high 32 bits.
+ if (_BitScanReverse(&r, static_cast<uint32_t>(x >> 32))) return 63 ^ (r + 32);
+ // Scan the low 32 bits.
+ _BitScanReverse(&r, static_cast<uint32_t>(x));
+# endif
+ FMT_ASSERT(x != 0, "");
+ FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
+ return 63 ^ static_cast<int>(r);
+}
+# define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
+
+inline auto ctz(uint32_t x) -> int {
+ unsigned long r = 0;
+ _BitScanForward(&r, x);
+ FMT_ASSERT(x != 0, "");
+ FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
+ return static_cast<int>(r);
+}
+# define FMT_BUILTIN_CTZ(n) detail::ctz(n)
+
+inline auto ctzll(uint64_t x) -> int {
+ unsigned long r = 0;
+ FMT_ASSERT(x != 0, "");
+ FMT_MSC_WARNING(suppress : 6102) // Suppress a bogus static analysis warning.
+# ifdef _WIN64
+ _BitScanForward64(&r, x);
+# else
+ // Scan the low 32 bits.
+ if (_BitScanForward(&r, static_cast<uint32_t>(x))) return static_cast<int>(r);
+ // Scan the high 32 bits.
+ _BitScanForward(&r, static_cast<uint32_t>(x >> 32));
+ r += 32;
+# endif
+ return static_cast<int>(r);
+}
+# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n)
+} // namespace detail
+FMT_END_NAMESPACE
+#endif
+
+#ifdef FMT_HEADER_ONLY
+# define FMT_HEADER_ONLY_CONSTEXPR20 FMT_CONSTEXPR20
+#else
+# define FMT_HEADER_ONLY_CONSTEXPR20
+#endif
+
+FMT_BEGIN_NAMESPACE
+namespace detail {
+
+template <typename Streambuf> class formatbuf : public Streambuf {
+ private:
+ using char_type = typename Streambuf::char_type;
+ using streamsize = decltype(std::declval<Streambuf>().sputn(nullptr, 0));
+ using int_type = typename Streambuf::int_type;
+ using traits_type = typename Streambuf::traits_type;
+
+ buffer<char_type>& buffer_;
+
+ public:
+ explicit formatbuf(buffer<char_type>& buf) : buffer_(buf) {}
+
+ protected:
+ // The put area is always empty. This makes the implementation simpler and has
+ // the advantage that the streambuf and the buffer are always in sync and
+ // sputc never writes into uninitialized memory. A disadvantage is that each
+ // call to sputc always results in a (virtual) call to overflow. There is no
+ // disadvantage here for sputn since this always results in a call to xsputn.
+
+ auto overflow(int_type ch) -> int_type override {
+ if (!traits_type::eq_int_type(ch, traits_type::eof()))
+ buffer_.push_back(static_cast<char_type>(ch));
+ return ch;
+ }
+
+ auto xsputn(const char_type* s, streamsize count) -> streamsize override {
+ buffer_.append(s, s + count);
+ return count;
+ }
+};
+
+// Implementation of std::bit_cast for pre-C++20.
+template <typename To, typename From>
+FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To {
+ static_assert(sizeof(To) == sizeof(From), "size mismatch");
+#ifdef __cpp_lib_bit_cast
+ if (is_constant_evaluated()) return std::bit_cast<To>(from);
+#endif
+ auto to = To();
+ std::memcpy(&to, &from, sizeof(to));
+ return to;
+}
+
+inline auto is_big_endian() -> bool {
+#ifdef _WIN32
+ return false;
+#elif defined(__BIG_ENDIAN__)
+ return true;
+#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
+ return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
+#else
+ struct bytes {
+ char data[sizeof(int)];
+ };
+ return bit_cast<bytes>(1).data[0] == 0;
+#endif
+}
+
+// A fallback implementation of uintptr_t for systems that lack it.
+struct fallback_uintptr {
+ unsigned char value[sizeof(void*)];
+
+ fallback_uintptr() = default;
+ explicit fallback_uintptr(const void* p) {
+ *this = bit_cast<fallback_uintptr>(p);
+ if (const_check(is_big_endian())) {
+ for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j)
+ std::swap(value[i], value[j]);
+ }
+ }
+};
+#ifdef UINTPTR_MAX
+using uintptr_t = ::uintptr_t;
+inline auto to_uintptr(const void* p) -> uintptr_t {
+ return bit_cast<uintptr_t>(p);
+}
+#else
+using uintptr_t = fallback_uintptr;
+inline auto to_uintptr(const void* p) -> fallback_uintptr {
+ return fallback_uintptr(p);
+}
+#endif
+
+// Returns the largest possible value for type T. Same as
+// std::numeric_limits<T>::max() but shorter and not affected by the max macro.
+template <typename T> constexpr auto max_value() -> T {
+ return (std::numeric_limits<T>::max)();
+}
+template <typename T> constexpr auto num_bits() -> int {
+ return std::numeric_limits<T>::digits;
+}
+// std::numeric_limits<T>::digits may return 0 for 128-bit ints.
+template <> constexpr auto num_bits<int128_t>() -> int { return 128; }
+template <> constexpr auto num_bits<uint128_t>() -> int { return 128; }
+template <> constexpr auto num_bits<fallback_uintptr>() -> int {
+ return static_cast<int>(sizeof(void*) *
+ std::numeric_limits<unsigned char>::digits);
+}
+
+FMT_INLINE void assume(bool condition) {
+ (void)condition;
+#if FMT_HAS_BUILTIN(__builtin_assume)
+ __builtin_assume(condition);
+#endif
+}
+
+// An approximation of iterator_t for pre-C++20 systems.
+template <typename T>
+using iterator_t = decltype(std::begin(std::declval<T&>()));
+template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
+
+// A workaround for std::string not having mutable data() until C++17.
+template <typename Char>
+inline auto get_data(std::basic_string<Char>& s) -> Char* {
+ return &s[0];
+}
+template <typename Container>
+inline auto get_data(Container& c) -> typename Container::value_type* {
+ return c.data();
+}
+
+#if defined(_SECURE_SCL) && _SECURE_SCL
+// Make a checked iterator to avoid MSVC warnings.
+template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
+template <typename T>
+constexpr auto make_checked(T* p, size_t size) -> checked_ptr<T> {
+ return {p, size};
+}
+#else
+template <typename T> using checked_ptr = T*;
+template <typename T> constexpr auto make_checked(T* p, size_t) -> T* {
+ return p;
+}
+#endif
+
+// Attempts to reserve space for n extra characters in the output range.
+// Returns a pointer to the reserved range or a reference to it.
+template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
+#if FMT_CLANG_VERSION >= 307 && !FMT_ICC_VERSION
+__attribute__((no_sanitize("undefined")))
+#endif
+inline auto
+reserve(std::back_insert_iterator<Container> it, size_t n)
+ -> checked_ptr<typename Container::value_type> {
+ Container& c = get_container(it);
+ size_t size = c.size();
+ c.resize(size + n);
+ return make_checked(get_data(c) + size, n);
+}
+
+template <typename T>
+inline auto reserve(buffer_appender<T> it, size_t n) -> buffer_appender<T> {
+ buffer<T>& buf = get_container(it);
+ buf.try_reserve(buf.size() + n);
+ return it;
+}
+
+template <typename Iterator>
+constexpr auto reserve(Iterator& it, size_t) -> Iterator& {
+ return it;
+}
+
+template <typename OutputIt>
+using reserve_iterator =
+ remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
+
+template <typename T, typename OutputIt>
+constexpr auto to_pointer(OutputIt, size_t) -> T* {
+ return nullptr;
+}
+template <typename T> auto to_pointer(buffer_appender<T> it, size_t n) -> T* {
+ buffer<T>& buf = get_container(it);
+ auto size = buf.size();
+ if (buf.capacity() < size + n) return nullptr;
+ buf.try_resize(size + n);
+ return buf.data() + size;
+}
+
+template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
+inline auto base_iterator(std::back_insert_iterator<Container>& it,
+ checked_ptr<typename Container::value_type>)
+ -> std::back_insert_iterator<Container> {
+ return it;
+}
+
+template <typename Iterator>
+constexpr auto base_iterator(Iterator, Iterator it) -> Iterator {
+ return it;
+}
+
+// <algorithm> is spectacularly slow to compile in C++20 so use a simple fill_n
+// instead (#1998).
+template <typename OutputIt, typename Size, typename T>
+FMT_CONSTEXPR auto fill_n(OutputIt out, Size count, const T& value)
+ -> OutputIt {
+ for (Size i = 0; i < count; ++i) *out++ = value;
+ return out;
+}
+template <typename T, typename Size>
+FMT_CONSTEXPR20 auto fill_n(T* out, Size count, char value) -> T* {
+ if (is_constant_evaluated()) {
+ return fill_n<T*, Size, T>(out, count, value);
+ }
+ std::memset(out, value, to_unsigned(count));
+ return out + count;
+}
+
+#ifdef __cpp_char8_t
+using char8_type = char8_t;
+#else
+enum char8_type : unsigned char {};
+#endif
+
+template <typename OutChar, typename InputIt, typename OutputIt>
+FMT_CONSTEXPR FMT_NOINLINE auto copy_str_noinline(InputIt begin, InputIt end,
+ OutputIt out) -> OutputIt {
+ return copy_str<OutChar>(begin, end, out);
+}
+
+// A public domain branchless UTF-8 decoder by Christopher Wellons:
+// https://github.com/skeeto/branchless-utf8
+/* Decode the next character, c, from s, reporting errors in e.
+ *
+ * Since this is a branchless decoder, four bytes will be read from the
+ * buffer regardless of the actual length of the next character. This
+ * means the buffer _must_ have at least three bytes of zero padding
+ * following the end of the data stream.
+ *
+ * Errors are reported in e, which will be non-zero if the parsed
+ * character was somehow invalid: invalid byte sequence, non-canonical
+ * encoding, or a surrogate half.
+ *
+ * The function returns a pointer to the next character. When an error
+ * occurs, this pointer will be a guess that depends on the particular
+ * error, but it will always advance at least one byte.
+ */
+FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e)
+ -> const char* {
+ constexpr const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
+ constexpr const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
+ constexpr const int shiftc[] = {0, 18, 12, 6, 0};
+ constexpr const int shifte[] = {0, 6, 4, 2, 0};
+
+ int len = code_point_length(s);
+ const char* next = s + len;
+
+ // Assume a four-byte character and load four bytes. Unused bits are
+ // shifted out.
+ *c = uint32_t(s[0] & masks[len]) << 18;
+ *c |= uint32_t(s[1] & 0x3f) << 12;
+ *c |= uint32_t(s[2] & 0x3f) << 6;
+ *c |= uint32_t(s[3] & 0x3f) << 0;
+ *c >>= shiftc[len];
+
+ // Accumulate the various error conditions.
+ using uchar = unsigned char;
+ *e = (*c < mins[len]) << 6; // non-canonical encoding
+ *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half?
+ *e |= (*c > 0x10FFFF) << 8; // out of range?
+ *e |= (uchar(s[1]) & 0xc0) >> 2;
+ *e |= (uchar(s[2]) & 0xc0) >> 4;
+ *e |= uchar(s[3]) >> 6;
+ *e ^= 0x2a; // top two bits of each tail byte correct?
+ *e >>= shifte[len];
+
+ return next;
+}
+
+constexpr uint32_t invalid_code_point = ~uint32_t();
+
+// Invokes f(cp, sv) for every code point cp in s with sv being the string view
+// corresponding to the code point. cp is invalid_code_point on error.
+template <typename F>
+FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) {
+ auto decode = [f](const char* buf_ptr, const char* ptr) {
+ auto cp = uint32_t();
+ auto error = 0;
+ auto end = utf8_decode(buf_ptr, &cp, &error);
+ bool result = f(error ? invalid_code_point : cp,
+ string_view(ptr, to_unsigned(end - buf_ptr)));
+ return result ? end : nullptr;
+ };
+ auto p = s.data();
+ const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars.
+ if (s.size() >= block_size) {
+ for (auto end = p + s.size() - block_size + 1; p < end;) {
+ p = decode(p, p);
+ if (!p) return;
+ }
+ }
+ if (auto num_chars_left = s.data() + s.size() - p) {
+ char buf[2 * block_size - 1] = {};
+ copy_str<char>(p, p + num_chars_left, buf);
+ const char* buf_ptr = buf;
+ do {
+ auto end = decode(buf_ptr, p);
+ if (!end) return;
+ p += end - buf_ptr;
+ buf_ptr = end;
+ } while (buf_ptr - buf < num_chars_left);
+ }
+}
+
+template <typename Char>
+inline auto compute_width(basic_string_view<Char> s) -> size_t {
+ return s.size();
+}
+
+// Computes approximate display width of a UTF-8 string.
+FMT_CONSTEXPR inline size_t compute_width(string_view s) {
+ size_t num_code_points = 0;
+ // It is not a lambda for compatibility with C++14.
+ struct count_code_points {
+ size_t* count;
+ FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool {
+ *count += detail::to_unsigned(
+ 1 +
+ (cp >= 0x1100 &&
+ (cp <= 0x115f || // Hangul Jamo init. consonants
+ cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET
+ cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET
+ // CJK ... Yi except IDEOGRAPHIC HALF FILL SPACE:
+ (cp >= 0x2e80 && cp <= 0xa4cf && cp != 0x303f) ||
+ (cp >= 0xac00 && cp <= 0xd7a3) || // Hangul Syllables
+ (cp >= 0xf900 && cp <= 0xfaff) || // CJK Compatibility Ideographs
+ (cp >= 0xfe10 && cp <= 0xfe19) || // Vertical Forms
+ (cp >= 0xfe30 && cp <= 0xfe6f) || // CJK Compatibility Forms
+ (cp >= 0xff00 && cp <= 0xff60) || // Fullwidth Forms
+ (cp >= 0xffe0 && cp <= 0xffe6) || // Fullwidth Forms
+ (cp >= 0x20000 && cp <= 0x2fffd) || // CJK
+ (cp >= 0x30000 && cp <= 0x3fffd) ||
+ // Miscellaneous Symbols and Pictographs + Emoticons:
+ (cp >= 0x1f300 && cp <= 0x1f64f) ||
+ // Supplemental Symbols and Pictographs:
+ (cp >= 0x1f900 && cp <= 0x1f9ff))));
+ return true;
+ }
+ };
+ for_each_codepoint(s, count_code_points{&num_code_points});
+ return num_code_points;
+}
+
+inline auto compute_width(basic_string_view<char8_type> s) -> size_t {
+ return compute_width(basic_string_view<char>(
+ reinterpret_cast<const char*>(s.data()), s.size()));
+}
+
+template <typename Char>
+inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
+ size_t size = s.size();
+ return n < size ? n : size;
+}
+
+// Calculates the index of the nth code point in a UTF-8 string.
+inline auto code_point_index(basic_string_view<char8_type> s, size_t n)
+ -> size_t {
+ const char8_type* data = s.data();
+ size_t num_code_points = 0;
+ for (size_t i = 0, size = s.size(); i != size; ++i) {
+ if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i;
+ }
+ return s.size();
+}
+
+template <typename T, bool = std::is_floating_point<T>::value>
+struct is_fast_float : bool_constant<std::numeric_limits<T>::is_iec559 &&
+ sizeof(T) <= sizeof(double)> {};
+template <typename T> struct is_fast_float<T, false> : std::false_type {};
+
+#ifndef FMT_USE_FULL_CACHE_DRAGONBOX
+# define FMT_USE_FULL_CACHE_DRAGONBOX 0
+#endif
+
+template <typename T>
+template <typename U>
+void buffer<T>::append(const U* begin, const U* end) {
+ while (begin != end) {
+ auto count = to_unsigned(end - begin);
+ try_reserve(size_ + count);
+ auto free_cap = capacity_ - size_;
+ if (free_cap < count) count = free_cap;
+ std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count));
+ size_ += count;
+ begin += count;
+ }
+}
+
+template <typename T, typename Enable = void>
+struct is_locale : std::false_type {};
+template <typename T>
+struct is_locale<T, void_t<decltype(T::classic())>> : std::true_type {};
+} // namespace detail
+
+FMT_MODULE_EXPORT_BEGIN
+
+// The number of characters to store in the basic_memory_buffer object itself
+// to avoid dynamic memory allocation.
+enum { inline_buffer_size = 500 };
+
+/**
+ \rst
+ A dynamically growing memory buffer for trivially copyable/constructible types
+ with the first ``SIZE`` elements stored in the object itself.
+
+ You can use the ``memory_buffer`` type alias for ``char`` instead.
+
+ **Example**::
+
+ auto out = fmt::memory_buffer();
+ format_to(std::back_inserter(out), "The answer is {}.", 42);
+
+ This will append the following output to the ``out`` object:
+
+ .. code-block:: none
+
+ The answer is 42.
+
+ The output can be converted to an ``std::string`` with ``to_string(out)``.
+ \endrst
+ */
+template <typename T, size_t SIZE = inline_buffer_size,
+ typename Allocator = std::allocator<T>>
+class basic_memory_buffer final : public detail::buffer<T> {
+ private:
+ T store_[SIZE];
+
+ // Don't inherit from Allocator avoid generating type_info for it.
+ Allocator alloc_;
+
+ // Deallocate memory allocated by the buffer.
+ FMT_CONSTEXPR20 void deallocate() {
+ T* data = this->data();
+ if (data != store_) alloc_.deallocate(data, this->capacity());
+ }
+
+ protected:
+ FMT_CONSTEXPR20 void grow(size_t size) override;
+
+ public:
+ using value_type = T;
+ using const_reference = const T&;
+
+ FMT_CONSTEXPR20 explicit basic_memory_buffer(
+ const Allocator& alloc = Allocator())
+ : alloc_(alloc) {
+ this->set(store_, SIZE);
+ if (detail::is_constant_evaluated()) {
+ detail::fill_n(store_, SIZE, T{});
+ }
+ }
+ FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); }
+
+ private:
+ // Move data from other to this buffer.
+ FMT_CONSTEXPR20 void move(basic_memory_buffer& other) {
+ alloc_ = std::move(other.alloc_);
+ T* data = other.data();
+ size_t size = other.size(), capacity = other.capacity();
+ if (data == other.store_) {
+ this->set(store_, capacity);
+ if (detail::is_constant_evaluated()) {
+ detail::copy_str<T>(other.store_, other.store_ + size,
+ detail::make_checked(store_, capacity));
+ } else {
+ std::uninitialized_copy(other.store_, other.store_ + size,
+ detail::make_checked(store_, capacity));
+ }
+ } else {
+ this->set(data, capacity);
+ // Set pointer to the inline array so that delete is not called
+ // when deallocating.
+ other.set(other.store_, 0);
+ }
+ this->resize(size);
+ }
+
+ public:
+ /**
+ \rst
+ Constructs a :class:`fmt::basic_memory_buffer` object moving the content
+ of the other object to it.
+ \endrst
+ */
+ FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other)
+ FMT_NOEXCEPT {
+ move(other);
+ }
+
+ /**
+ \rst
+ Moves the content of the other ``basic_memory_buffer`` object to this one.
+ \endrst
+ */
+ auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT
+ -> basic_memory_buffer& {
+ FMT_ASSERT(this != &other, "");
+ deallocate();
+ move(other);
+ return *this;
+ }
+
+ // Returns a copy of the allocator associated with this buffer.
+ auto get_allocator() const -> Allocator { return alloc_; }
+
+ /**
+ Resizes the buffer to contain *count* elements. If T is a POD type new
+ elements may not be initialized.
+ */
+ FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); }
+
+ /** Increases the buffer capacity to *new_capacity*. */
+ void reserve(size_t new_capacity) { this->try_reserve(new_capacity); }
+
+ // Directly append data into the buffer
+ using detail::buffer<T>::append;
+ template <typename ContiguousRange>
+ void append(const ContiguousRange& range) {
+ append(range.data(), range.data() + range.size());
+ }
+};
+
+template <typename T, size_t SIZE, typename Allocator>
+FMT_CONSTEXPR20 void basic_memory_buffer<T, SIZE, Allocator>::grow(
+ size_t size) {
+#ifdef FMT_FUZZ
+ if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much");
+#endif
+ const size_t max_size = std::allocator_traits<Allocator>::max_size(alloc_);
+ size_t old_capacity = this->capacity();
+ size_t new_capacity = old_capacity + old_capacity / 2;
+ if (size > new_capacity)
+ new_capacity = size;
+ else if (new_capacity > max_size)
+ new_capacity = size > max_size ? size : max_size;
+ T* old_data = this->data();
+ T* new_data =
+ std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
+ // The following code doesn't throw, so the raw pointer above doesn't leak.
+ std::uninitialized_copy(old_data, old_data + this->size(),
+ detail::make_checked(new_data, new_capacity));
+ this->set(new_data, new_capacity);
+ // deallocate must not throw according to the standard, but even if it does,
+ // the buffer already uses the new storage and will deallocate it in
+ // destructor.
+ if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
+}
+
+using memory_buffer = basic_memory_buffer<char>;
+
+template <typename T, size_t SIZE, typename Allocator>
+struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
+};
+
+namespace detail {
+FMT_API void print(std::FILE*, string_view);
+}
+
+/** A formatting error such as invalid format string. */
+FMT_CLASS_API
+class FMT_API format_error : public std::runtime_error {
+ public:
+ explicit format_error(const char* message) : std::runtime_error(message) {}
+ explicit format_error(const std::string& message)
+ : std::runtime_error(message) {}
+ format_error(const format_error&) = default;
+ format_error& operator=(const format_error&) = default;
+ format_error(format_error&&) = default;
+ format_error& operator=(format_error&&) = default;
+ ~format_error() FMT_NOEXCEPT override FMT_MSC_DEFAULT;
+};
+
+/**
+ \rst
+ Constructs a `~fmt::format_arg_store` object that contains references
+ to arguments and can be implicitly converted to `~fmt::format_args`.
+ If ``fmt`` is a compile-time string then `make_args_checked` checks
+ its validity at compile time.
+ \endrst
+ */
+template <typename... Args, typename S, typename Char = char_t<S>>
+FMT_INLINE auto make_args_checked(const S& fmt,
+ const remove_reference_t<Args>&... args)
+ -> format_arg_store<buffer_context<Char>, remove_reference_t<Args>...> {
+ static_assert(
+ detail::count<(
+ std::is_base_of<detail::view, remove_reference_t<Args>>::value &&
+ std::is_reference<Args>::value)...>() == 0,
+ "passing views as lvalues is disallowed");
+ detail::check_format_string<Args...>(fmt);
+ return {args...};
+}
+
+// compile-time support
+namespace detail_exported {
+#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+template <typename Char, size_t N> struct fixed_string {
+ constexpr fixed_string(const Char (&str)[N]) {
+ detail::copy_str<Char, const Char*, Char*>(static_cast<const Char*>(str),
+ str + N, data);
+ }
+ Char data[N]{};
+};
+#endif
+
+// Converts a compile-time string to basic_string_view.
+template <typename Char, size_t N>
+constexpr auto compile_string_to_view(const Char (&s)[N])
+ -> basic_string_view<Char> {
+ // Remove trailing NUL character if needed. Won't be present if this is used
+ // with a raw character array (i.e. not defined as a string).
+ return {s, N - (std::char_traits<Char>::to_int_type(s[N - 1]) == 0 ? 1 : 0)};
+}
+template <typename Char>
+constexpr auto compile_string_to_view(detail::std_string_view<Char> s)
+ -> basic_string_view<Char> {
+ return {s.data(), s.size()};
+}
+} // namespace detail_exported
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+template <typename T> struct is_integral : std::is_integral<T> {};
+template <> struct is_integral<int128_t> : std::true_type {};
+template <> struct is_integral<uint128_t> : std::true_type {};
+
+template <typename T>
+using is_signed =
+ std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
+ std::is_same<T, int128_t>::value>;
+
+// Returns true if value is negative, false otherwise.
+// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
+template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
+FMT_CONSTEXPR auto is_negative(T value) -> bool {
+ return value < 0;
+}
+template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
+FMT_CONSTEXPR auto is_negative(T) -> bool {
+ return false;
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t {
+ return (std::is_same<T, float>::value && FMT_USE_FLOAT) ||
+ (std::is_same<T, double>::value && FMT_USE_DOUBLE) ||
+ (std::is_same<T, long double>::value && FMT_USE_LONG_DOUBLE);
+}
+
+// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
+// represent all values of an integral type T.
+template <typename T>
+using uint32_or_64_or_128_t =
+ conditional_t<num_bits<T>() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS,
+ uint32_t,
+ conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
+template <typename T>
+using uint64_or_128_t = conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>;
+
+#define FMT_POWERS_OF_10(factor) \
+ factor * 10, (factor)*100, (factor)*1000, (factor)*10000, (factor)*100000, \
+ (factor)*1000000, (factor)*10000000, (factor)*100000000, \
+ (factor)*1000000000
+
+// Converts value in the range [0, 100) to a string.
+constexpr const char* digits2(size_t value) {
+ // GCC generates slightly better code when value is pointer-size.
+ return &"0001020304050607080910111213141516171819"
+ "2021222324252627282930313233343536373839"
+ "4041424344454647484950515253545556575859"
+ "6061626364656667686970717273747576777879"
+ "8081828384858687888990919293949596979899"[value * 2];
+}
+
+// Sign is a template parameter to workaround a bug in gcc 4.8.
+template <typename Char, typename Sign> constexpr Char sign(Sign s) {
+#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604
+ static_assert(std::is_same<Sign, sign_t>::value, "");
+#endif
+ return static_cast<Char>("\0-+ "[s]);
+}
+
+template <typename T> FMT_CONSTEXPR auto count_digits_fallback(T n) -> int {
+ int count = 1;
+ for (;;) {
+ // Integer division is slow so do it for a group of four digits instead
+ // of for every digit. The idea comes from the talk by Alexandrescu
+ // "Three Optimization Tips for C++". See speed-test for a comparison.
+ if (n < 10) return count;
+ if (n < 100) return count + 1;
+ if (n < 1000) return count + 2;
+ if (n < 10000) return count + 3;
+ n /= 10000u;
+ count += 4;
+ }
+}
+#if FMT_USE_INT128
+FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int {
+ return count_digits_fallback(n);
+}
+#endif
+
+#ifdef FMT_BUILTIN_CLZLL
+// It is a separate function rather than a part of count_digits to workaround
+// the lack of static constexpr in constexpr functions.
+inline auto do_count_digits(uint64_t n) -> int {
+ // This has comparable performance to the version by Kendall Willets
+ // (https://github.com/fmtlib/format-benchmark/blob/master/digits10)
+ // but uses smaller tables.
+ // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)).
+ static constexpr uint8_t bsr2log10[] = {
+ 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10,
+ 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15,
+ 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20};
+ auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63];
+ static constexpr const uint64_t zero_or_powers_of_10[] = {
+ 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL),
+ 10000000000000000000ULL};
+ return t - (n < zero_or_powers_of_10[t]);
+}
+#endif
+
+// Returns the number of decimal digits in n. Leading zeros are not counted
+// except for n == 0 in which case count_digits returns 1.
+FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int {
+#ifdef FMT_BUILTIN_CLZLL
+ if (!is_constant_evaluated()) {
+ return do_count_digits(n);
+ }
+#endif
+ return count_digits_fallback(n);
+}
+
+// Counts the number of digits in n. BITS = log2(radix).
+template <int BITS, typename UInt>
+FMT_CONSTEXPR auto count_digits(UInt n) -> int {
+#ifdef FMT_BUILTIN_CLZ
+ if (num_bits<UInt>() == 32)
+ return (FMT_BUILTIN_CLZ(static_cast<uint32_t>(n) | 1) ^ 31) / BITS + 1;
+#endif
+ // Lambda avoids unreachable code warnings from NVHPC.
+ return [](UInt m) {
+ int num_digits = 0;
+ do {
+ ++num_digits;
+ } while ((m >>= BITS) != 0);
+ return num_digits;
+ }(n);
+}
+
+template <> auto count_digits<4>(detail::fallback_uintptr n) -> int;
+
+#ifdef FMT_BUILTIN_CLZ
+// It is a separate function rather than a part of count_digits to workaround
+// the lack of static constexpr in constexpr functions.
+FMT_INLINE auto do_count_digits(uint32_t n) -> int {
+// An optimization by Kendall Willets from https://bit.ly/3uOIQrB.
+// This increments the upper 32 bits (log10(T) - 1) when >= T is added.
+# define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T)
+ static constexpr uint64_t table[] = {
+ FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8
+ FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64
+ FMT_INC(100), FMT_INC(100), FMT_INC(100), // 512
+ FMT_INC(1000), FMT_INC(1000), FMT_INC(1000), // 4096
+ FMT_INC(10000), FMT_INC(10000), FMT_INC(10000), // 32k
+ FMT_INC(100000), FMT_INC(100000), FMT_INC(100000), // 256k
+ FMT_INC(1000000), FMT_INC(1000000), FMT_INC(1000000), // 2048k
+ FMT_INC(10000000), FMT_INC(10000000), FMT_INC(10000000), // 16M
+ FMT_INC(100000000), FMT_INC(100000000), FMT_INC(100000000), // 128M
+ FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M
+ FMT_INC(1000000000), FMT_INC(1000000000) // 4B
+ };
+ auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31];
+ return static_cast<int>((n + inc) >> 32);
+}
+#endif
+
+// Optional version of count_digits for better performance on 32-bit platforms.
+FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int {
+#ifdef FMT_BUILTIN_CLZ
+ if (!is_constant_evaluated()) {
+ return do_count_digits(n);
+ }
+#endif
+ return count_digits_fallback(n);
+}
+
+template <typename Int> constexpr auto digits10() FMT_NOEXCEPT -> int {
+ return std::numeric_limits<Int>::digits10;
+}
+template <> constexpr auto digits10<int128_t>() FMT_NOEXCEPT -> int {
+ return 38;
+}
+template <> constexpr auto digits10<uint128_t>() FMT_NOEXCEPT -> int {
+ return 38;
+}
+
+template <typename Char> struct thousands_sep_result {
+ std::string grouping;
+ Char thousands_sep;
+};
+
+template <typename Char>
+FMT_API auto thousands_sep_impl(locale_ref loc) -> thousands_sep_result<Char>;
+template <typename Char>
+inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<Char> {
+ auto result = thousands_sep_impl<char>(loc);
+ return {result.grouping, Char(result.thousands_sep)};
+}
+template <>
+inline auto thousands_sep(locale_ref loc) -> thousands_sep_result<wchar_t> {
+ return thousands_sep_impl<wchar_t>(loc);
+}
+
+template <typename Char>
+FMT_API auto decimal_point_impl(locale_ref loc) -> Char;
+template <typename Char> inline auto decimal_point(locale_ref loc) -> Char {
+ return Char(decimal_point_impl<char>(loc));
+}
+template <> inline auto decimal_point(locale_ref loc) -> wchar_t {
+ return decimal_point_impl<wchar_t>(loc);
+}
+
+// Compares two characters for equality.
+template <typename Char> auto equal2(const Char* lhs, const char* rhs) -> bool {
+ return lhs[0] == Char(rhs[0]) && lhs[1] == Char(rhs[1]);
+}
+inline auto equal2(const char* lhs, const char* rhs) -> bool {
+ return memcmp(lhs, rhs, 2) == 0;
+}
+
+// Copies two characters from src to dst.
+template <typename Char>
+FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) {
+ if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) {
+ memcpy(dst, src, 2);
+ return;
+ }
+ *dst++ = static_cast<Char>(*src++);
+ *dst = static_cast<Char>(*src);
+}
+
+template <typename Iterator> struct format_decimal_result {
+ Iterator begin;
+ Iterator end;
+};
+
+// Formats a decimal unsigned integer value writing into out pointing to a
+// buffer of specified size. The caller must ensure that the buffer is large
+// enough.
+template <typename Char, typename UInt>
+FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size)
+ -> format_decimal_result<Char*> {
+ FMT_ASSERT(size >= count_digits(value), "invalid digit count");
+ out += size;
+ Char* end = out;
+ while (value >= 100) {
+ // Integer division is slow so do it for a group of two digits instead
+ // of for every digit. The idea comes from the talk by Alexandrescu
+ // "Three Optimization Tips for C++". See speed-test for a comparison.
+ out -= 2;
+ copy2(out, digits2(static_cast<size_t>(value % 100)));
+ value /= 100;
+ }
+ if (value < 10) {
+ *--out = static_cast<Char>('0' + value);
+ return {out, end};
+ }
+ out -= 2;
+ copy2(out, digits2(static_cast<size_t>(value)));
+ return {out, end};
+}
+
+template <typename Char, typename UInt, typename Iterator,
+ FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
+inline auto format_decimal(Iterator out, UInt value, int size)
+ -> format_decimal_result<Iterator> {
+ // Buffer is large enough to hold all digits (digits10 + 1).
+ Char buffer[digits10<UInt>() + 1];
+ auto end = format_decimal(buffer, value, size).end;
+ return {out, detail::copy_str_noinline<Char>(buffer, end, out)};
+}
+
+template <unsigned BASE_BITS, typename Char, typename UInt>
+FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits,
+ bool upper = false) -> Char* {
+ buffer += num_digits;
+ Char* end = buffer;
+ do {
+ const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef";
+ unsigned digit = (value & ((1 << BASE_BITS) - 1));
+ *--buffer = static_cast<Char>(BASE_BITS < 4 ? static_cast<char>('0' + digit)
+ : digits[digit]);
+ } while ((value >>= BASE_BITS) != 0);
+ return end;
+}
+
+template <unsigned BASE_BITS, typename Char>
+auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits,
+ bool = false) -> Char* {
+ auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
+ int start = (num_digits + char_digits - 1) / char_digits - 1;
+ if (int start_digits = num_digits % char_digits) {
+ unsigned value = n.value[start--];
+ buffer = format_uint<BASE_BITS>(buffer, value, start_digits);
+ }
+ for (; start >= 0; --start) {
+ unsigned value = n.value[start];
+ buffer += char_digits;
+ auto p = buffer;
+ for (int i = 0; i < char_digits; ++i) {
+ unsigned digit = (value & ((1 << BASE_BITS) - 1));
+ *--p = static_cast<Char>("0123456789abcdef"[digit]);
+ value >>= BASE_BITS;
+ }
+ }
+ return buffer;
+}
+
+template <unsigned BASE_BITS, typename Char, typename It, typename UInt>
+inline auto format_uint(It out, UInt value, int num_digits, bool upper = false)
+ -> It {
+ if (auto ptr = to_pointer<Char>(out, to_unsigned(num_digits))) {
+ format_uint<BASE_BITS>(ptr, value, num_digits, upper);
+ return out;
+ }
+ // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
+ char buffer[num_bits<UInt>() / BASE_BITS + 1];
+ format_uint<BASE_BITS>(buffer, value, num_digits, upper);
+ return detail::copy_str_noinline<Char>(buffer, buffer + num_digits, out);
+}
+
+// A converter from UTF-8 to UTF-16.
+class utf8_to_utf16 {
+ private:
+ basic_memory_buffer<wchar_t> buffer_;
+
+ public:
+ FMT_API explicit utf8_to_utf16(string_view s);
+ operator basic_string_view<wchar_t>() const { return {&buffer_[0], size()}; }
+ auto size() const -> size_t { return buffer_.size() - 1; }
+ auto c_str() const -> const wchar_t* { return &buffer_[0]; }
+ auto str() const -> std::wstring { return {&buffer_[0], size()}; }
+};
+
+namespace dragonbox {
+
+// Type-specific information that Dragonbox uses.
+template <class T> struct float_info;
+
+template <> struct float_info<float> {
+ using carrier_uint = uint32_t;
+ static const int significand_bits = 23;
+ static const int exponent_bits = 8;
+ static const int min_exponent = -126;
+ static const int max_exponent = 127;
+ static const int exponent_bias = -127;
+ static const int decimal_digits = 9;
+ static const int kappa = 1;
+ static const int big_divisor = 100;
+ static const int small_divisor = 10;
+ static const int min_k = -31;
+ static const int max_k = 46;
+ static const int cache_bits = 64;
+ static const int divisibility_check_by_5_threshold = 39;
+ static const int case_fc_pm_half_lower_threshold = -1;
+ static const int case_fc_pm_half_upper_threshold = 6;
+ static const int case_fc_lower_threshold = -2;
+ static const int case_fc_upper_threshold = 6;
+ static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
+ static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
+ static const int shorter_interval_tie_lower_threshold = -35;
+ static const int shorter_interval_tie_upper_threshold = -35;
+ static const int max_trailing_zeros = 7;
+};
+
+template <> struct float_info<double> {
+ using carrier_uint = uint64_t;
+ static const int significand_bits = 52;
+ static const int exponent_bits = 11;
+ static const int min_exponent = -1022;
+ static const int max_exponent = 1023;
+ static const int exponent_bias = -1023;
+ static const int decimal_digits = 17;
+ static const int kappa = 2;
+ static const int big_divisor = 1000;
+ static const int small_divisor = 100;
+ static const int min_k = -292;
+ static const int max_k = 326;
+ static const int cache_bits = 128;
+ static const int divisibility_check_by_5_threshold = 86;
+ static const int case_fc_pm_half_lower_threshold = -2;
+ static const int case_fc_pm_half_upper_threshold = 9;
+ static const int case_fc_lower_threshold = -4;
+ static const int case_fc_upper_threshold = 9;
+ static const int case_shorter_interval_left_endpoint_lower_threshold = 2;
+ static const int case_shorter_interval_left_endpoint_upper_threshold = 3;
+ static const int shorter_interval_tie_lower_threshold = -77;
+ static const int shorter_interval_tie_upper_threshold = -77;
+ static const int max_trailing_zeros = 16;
+};
+
+template <typename T> struct decimal_fp {
+ using significand_type = typename float_info<T>::carrier_uint;
+ significand_type significand;
+ int exponent;
+};
+
+template <typename T>
+FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp<T>;
+} // namespace dragonbox
+
+template <typename T>
+constexpr auto exponent_mask() ->
+ typename dragonbox::float_info<T>::carrier_uint {
+ using uint = typename dragonbox::float_info<T>::carrier_uint;
+ return ((uint(1) << dragonbox::float_info<T>::exponent_bits) - 1)
+ << dragonbox::float_info<T>::significand_bits;
+}
+
+// Writes the exponent exp in the form "[+-]d{2,3}" to buffer.
+template <typename Char, typename It>
+FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It {
+ FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range");
+ if (exp < 0) {
+ *it++ = static_cast<Char>('-');
+ exp = -exp;
+ } else {
+ *it++ = static_cast<Char>('+');
+ }
+ if (exp >= 100) {
+ const char* top = digits2(to_unsigned(exp / 100));
+ if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
+ *it++ = static_cast<Char>(top[1]);
+ exp %= 100;
+ }
+ const char* d = digits2(to_unsigned(exp));
+ *it++ = static_cast<Char>(d[0]);
+ *it++ = static_cast<Char>(d[1]);
+ return it;
+}
+
+template <typename T>
+FMT_HEADER_ONLY_CONSTEXPR20 auto format_float(T value, int precision,
+ float_specs specs,
+ buffer<char>& buf) -> int;
+
+// Formats a floating-point number with snprintf.
+template <typename T>
+auto snprintf_float(T value, int precision, float_specs specs,
+ buffer<char>& buf) -> int;
+
+template <typename T> constexpr auto promote_float(T value) -> T {
+ return value;
+}
+constexpr auto promote_float(float value) -> double {
+ return static_cast<double>(value);
+}
+
+template <typename OutputIt, typename Char>
+FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n,
+ const fill_t<Char>& fill) -> OutputIt {
+ auto fill_size = fill.size();
+ if (fill_size == 1) return detail::fill_n(it, n, fill[0]);
+ auto data = fill.data();
+ for (size_t i = 0; i < n; ++i)
+ it = copy_str<Char>(data, data + fill_size, it);
+ return it;
+}
+
+// Writes the output of f, padded according to format specifications in specs.
+// size: output size in code units.
+// width: output display width in (terminal) column positions.
+template <align::type align = align::left, typename OutputIt, typename Char,
+ typename F>
+FMT_CONSTEXPR auto write_padded(OutputIt out,
+ const basic_format_specs<Char>& specs,
+ size_t size, size_t width, F&& f) -> OutputIt {
+ static_assert(align == align::left || align == align::right, "");
+ unsigned spec_width = to_unsigned(specs.width);
+ size_t padding = spec_width > width ? spec_width - width : 0;
+ // Shifts are encoded as string literals because static constexpr is not
+ // supported in constexpr functions.
+ auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01";
+ size_t left_padding = padding >> shifts[specs.align];
+ size_t right_padding = padding - left_padding;
+ auto it = reserve(out, size + padding * specs.fill.size());
+ if (left_padding != 0) it = fill(it, left_padding, specs.fill);
+ it = f(it);
+ if (right_padding != 0) it = fill(it, right_padding, specs.fill);
+ return base_iterator(out, it);
+}
+
+template <align::type align = align::left, typename OutputIt, typename Char,
+ typename F>
+constexpr auto write_padded(OutputIt out, const basic_format_specs<Char>& specs,
+ size_t size, F&& f) -> OutputIt {
+ return write_padded<align>(out, specs, size, size, f);
+}
+
+template <align::type align = align::left, typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write_bytes(OutputIt out, string_view bytes,
+ const basic_format_specs<Char>& specs)
+ -> OutputIt {
+ return write_padded<align>(
+ out, specs, bytes.size(), [bytes](reserve_iterator<OutputIt> it) {
+ const char* data = bytes.data();
+ return copy_str<Char>(data, data + bytes.size(), it);
+ });
+}
+
+template <typename Char, typename OutputIt, typename UIntPtr>
+auto write_ptr(OutputIt out, UIntPtr value,
+ const basic_format_specs<Char>* specs) -> OutputIt {
+ int num_digits = count_digits<4>(value);
+ auto size = to_unsigned(num_digits) + size_t(2);
+ auto write = [=](reserve_iterator<OutputIt> it) {
+ *it++ = static_cast<Char>('0');
+ *it++ = static_cast<Char>('x');
+ return format_uint<4, Char>(it, value, num_digits);
+ };
+ return specs ? write_padded<align::right>(out, *specs, size, write)
+ : base_iterator(out, write(reserve(out, size)));
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write_char(OutputIt out, Char value,
+ const basic_format_specs<Char>& specs)
+ -> OutputIt {
+ return write_padded(out, specs, 1, [=](reserve_iterator<OutputIt> it) {
+ *it++ = value;
+ return it;
+ });
+}
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out, Char value,
+ const basic_format_specs<Char>& specs,
+ locale_ref loc = {}) -> OutputIt {
+ return check_char_specs(specs)
+ ? write_char(out, value, specs)
+ : write(out, static_cast<int>(value), specs, loc);
+}
+
+// Data for write_int that doesn't depend on output iterator type. It is used to
+// avoid template code bloat.
+template <typename Char> struct write_int_data {
+ size_t size;
+ size_t padding;
+
+ FMT_CONSTEXPR write_int_data(int num_digits, unsigned prefix,
+ const basic_format_specs<Char>& specs)
+ : size((prefix >> 24) + to_unsigned(num_digits)), padding(0) {
+ if (specs.align == align::numeric) {
+ auto width = to_unsigned(specs.width);
+ if (width > size) {
+ padding = width - size;
+ size = width;
+ }
+ } else if (specs.precision > num_digits) {
+ size = (prefix >> 24) + to_unsigned(specs.precision);
+ padding = to_unsigned(specs.precision - num_digits);
+ }
+ }
+};
+
+// Writes an integer in the format
+// <left-padding><prefix><numeric-padding><digits><right-padding>
+// where <digits> are written by write_digits(it).
+// prefix contains chars in three lower bytes and the size in the fourth byte.
+template <typename OutputIt, typename Char, typename W>
+FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits,
+ unsigned prefix,
+ const basic_format_specs<Char>& specs,
+ W write_digits) -> OutputIt {
+ // Slightly faster check for specs.width == 0 && specs.precision == -1.
+ if ((specs.width | (specs.precision + 1)) == 0) {
+ auto it = reserve(out, to_unsigned(num_digits) + (prefix >> 24));
+ if (prefix != 0) {
+ for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
+ *it++ = static_cast<Char>(p & 0xff);
+ }
+ return base_iterator(out, write_digits(it));
+ }
+ auto data = write_int_data<Char>(num_digits, prefix, specs);
+ return write_padded<align::right>(
+ out, specs, data.size, [=](reserve_iterator<OutputIt> it) {
+ for (unsigned p = prefix & 0xffffff; p != 0; p >>= 8)
+ *it++ = static_cast<Char>(p & 0xff);
+ it = detail::fill_n(it, data.padding, static_cast<Char>('0'));
+ return write_digits(it);
+ });
+}
+
+template <typename Char> class digit_grouping {
+ private:
+ thousands_sep_result<Char> sep_;
+
+ struct next_state {
+ std::string::const_iterator group;
+ int pos;
+ };
+ next_state initial_state() const { return {sep_.grouping.begin(), 0}; }
+
+ // Returns the next digit group separator position.
+ int next(next_state& state) const {
+ if (!sep_.thousands_sep) return max_value<int>();
+ if (state.group == sep_.grouping.end())
+ return state.pos += sep_.grouping.back();
+ if (*state.group <= 0 || *state.group == max_value<char>())
+ return max_value<int>();
+ state.pos += *state.group++;
+ return state.pos;
+ }
+
+ public:
+ explicit digit_grouping(locale_ref loc, bool localized = true) {
+ if (localized)
+ sep_ = thousands_sep<Char>(loc);
+ else
+ sep_.thousands_sep = Char();
+ }
+ explicit digit_grouping(thousands_sep_result<Char> sep) : sep_(sep) {}
+
+ Char separator() const { return sep_.thousands_sep; }
+
+ int count_separators(int num_digits) const {
+ int count = 0;
+ auto state = initial_state();
+ while (num_digits > next(state)) ++count;
+ return count;
+ }
+
+ // Applies grouping to digits and write the output to out.
+ template <typename Out, typename C>
+ Out apply(Out out, basic_string_view<C> digits) const {
+ auto num_digits = static_cast<int>(digits.size());
+ auto separators = basic_memory_buffer<int>();
+ separators.push_back(0);
+ auto state = initial_state();
+ while (int i = next(state)) {
+ if (i >= num_digits) break;
+ separators.push_back(i);
+ }
+ for (int i = 0, sep_index = static_cast<int>(separators.size() - 1);
+ i < num_digits; ++i) {
+ if (num_digits - i == separators[sep_index]) {
+ *out++ = separator();
+ --sep_index;
+ }
+ *out++ = static_cast<Char>(digits[to_unsigned(i)]);
+ }
+ return out;
+ }
+};
+
+template <typename OutputIt, typename UInt, typename Char>
+auto write_int_localized(OutputIt out, UInt value, unsigned prefix,
+ const basic_format_specs<Char>& specs,
+ const digit_grouping<Char>& grouping) -> OutputIt {
+ static_assert(std::is_same<uint64_or_128_t<UInt>, UInt>::value, "");
+ int num_digits = count_digits(value);
+ char digits[40];
+ format_decimal(digits, value, num_digits);
+ unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits +
+ grouping.count_separators(num_digits));
+ return write_padded<align::right>(
+ out, specs, size, size, [&](reserve_iterator<OutputIt> it) {
+ if (prefix != 0) *it++ = static_cast<Char>(prefix);
+ return grouping.apply(it, string_view(digits, to_unsigned(num_digits)));
+ });
+}
+
+template <typename OutputIt, typename UInt, typename Char>
+auto write_int_localized(OutputIt& out, UInt value, unsigned prefix,
+ const basic_format_specs<Char>& specs, locale_ref loc)
+ -> bool {
+ auto grouping = digit_grouping<Char>(loc);
+ out = write_int_localized(out, value, prefix, specs, grouping);
+ return true;
+}
+
+FMT_CONSTEXPR inline void prefix_append(unsigned& prefix, unsigned value) {
+ prefix |= prefix != 0 ? value << 8 : value;
+ prefix += (1u + (value > 0xff ? 1 : 0)) << 24;
+}
+
+template <typename UInt> struct write_int_arg {
+ UInt abs_value;
+ unsigned prefix;
+};
+
+template <typename T>
+FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign)
+ -> write_int_arg<uint32_or_64_or_128_t<T>> {
+ auto prefix = 0u;
+ auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
+ if (is_negative(value)) {
+ prefix = 0x01000000 | '-';
+ abs_value = 0 - abs_value;
+ } else {
+ constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+',
+ 0x1000000u | ' '};
+ prefix = prefixes[sign];
+ }
+ return {abs_value, prefix};
+}
+
+template <typename Char, typename OutputIt, typename T>
+FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg<T> arg,
+ const basic_format_specs<Char>& specs,
+ locale_ref loc) -> OutputIt {
+ static_assert(std::is_same<T, uint32_or_64_or_128_t<T>>::value, "");
+ auto abs_value = arg.abs_value;
+ auto prefix = arg.prefix;
+ switch (specs.type) {
+ case presentation_type::none:
+ case presentation_type::dec: {
+ if (specs.localized &&
+ write_int_localized(out, static_cast<uint64_or_128_t<T>>(abs_value),
+ prefix, specs, loc)) {
+ return out;
+ }
+ auto num_digits = count_digits(abs_value);
+ return write_int(
+ out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
+ return format_decimal<Char>(it, abs_value, num_digits).end;
+ });
+ }
+ case presentation_type::hex_lower:
+ case presentation_type::hex_upper: {
+ bool upper = specs.type == presentation_type::hex_upper;
+ if (specs.alt)
+ prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0');
+ int num_digits = count_digits<4>(abs_value);
+ return write_int(
+ out, num_digits, prefix, specs, [=](reserve_iterator<OutputIt> it) {
+ return format_uint<4, Char>(it, abs_value, num_digits, upper);
+ });
+ }
+ case presentation_type::bin_lower:
+ case presentation_type::bin_upper: {
+ bool upper = specs.type == presentation_type::bin_upper;
+ if (specs.alt)
+ prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0');
+ int num_digits = count_digits<1>(abs_value);
+ return write_int(out, num_digits, prefix, specs,
+ [=](reserve_iterator<OutputIt> it) {
+ return format_uint<1, Char>(it, abs_value, num_digits);
+ });
+ }
+ case presentation_type::oct: {
+ int num_digits = count_digits<3>(abs_value);
+ // Octal prefix '0' is counted as a digit, so only add it if precision
+ // is not greater than the number of digits.
+ if (specs.alt && specs.precision <= num_digits && abs_value != 0)
+ prefix_append(prefix, '0');
+ return write_int(out, num_digits, prefix, specs,
+ [=](reserve_iterator<OutputIt> it) {
+ return format_uint<3, Char>(it, abs_value, num_digits);
+ });
+ }
+ case presentation_type::chr:
+ return write_char(out, static_cast<Char>(abs_value), specs);
+ default:
+ throw_format_error("invalid type specifier");
+ }
+ return out;
+}
+template <typename Char, typename OutputIt, typename T>
+FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline(
+ OutputIt out, write_int_arg<T> arg, const basic_format_specs<Char>& specs,
+ locale_ref loc) -> OutputIt {
+ return write_int(out, arg, specs, loc);
+}
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(is_integral<T>::value &&
+ !std::is_same<T, bool>::value &&
+ std::is_same<OutputIt, buffer_appender<Char>>::value)>
+FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
+ const basic_format_specs<Char>& specs,
+ locale_ref loc) -> OutputIt {
+ return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs,
+ loc);
+}
+// An inlined version of write used in format string compilation.
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(is_integral<T>::value &&
+ !std::is_same<T, bool>::value &&
+ !std::is_same<OutputIt, buffer_appender<Char>>::value)>
+FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value,
+ const basic_format_specs<Char>& specs,
+ locale_ref loc) -> OutputIt {
+ return write_int(out, make_write_int_arg(value, specs.sign), specs, loc);
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> s,
+ const basic_format_specs<Char>& specs) -> OutputIt {
+ auto data = s.data();
+ auto size = s.size();
+ if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
+ size = code_point_index(s, to_unsigned(specs.precision));
+ auto width =
+ specs.width != 0 ? compute_width(basic_string_view<Char>(data, size)) : 0;
+ return write_padded(out, specs, size, width,
+ [=](reserve_iterator<OutputIt> it) {
+ return copy_str<Char>(data, data + size, it);
+ });
+}
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out,
+ basic_string_view<type_identity_t<Char>> s,
+ const basic_format_specs<Char>& specs, locale_ref)
+ -> OutputIt {
+ check_string_type_spec(specs.type);
+ return write(out, s, specs);
+}
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
+ const basic_format_specs<Char>& specs, locale_ref)
+ -> OutputIt {
+ return check_cstring_type_spec(specs.type)
+ ? write(out, basic_string_view<Char>(s), specs, {})
+ : write_ptr<Char>(out, to_uintptr(s), &specs);
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isinf,
+ basic_format_specs<Char> specs,
+ const float_specs& fspecs) -> OutputIt {
+ auto str =
+ isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan");
+ constexpr size_t str_size = 3;
+ auto sign = fspecs.sign;
+ auto size = str_size + (sign ? 1 : 0);
+ // Replace '0'-padding with space for non-finite values.
+ const bool is_zero_fill =
+ specs.fill.size() == 1 && *specs.fill.data() == static_cast<Char>('0');
+ if (is_zero_fill) specs.fill[0] = static_cast<Char>(' ');
+ return write_padded(out, specs, size, [=](reserve_iterator<OutputIt> it) {
+ if (sign) *it++ = detail::sign<Char>(sign);
+ return copy_str<Char>(str, str + str_size, it);
+ });
+}
+
+// A decimal floating-point number significand * pow(10, exp).
+struct big_decimal_fp {
+ const char* significand;
+ int significand_size;
+ int exponent;
+};
+
+constexpr auto get_significand_size(const big_decimal_fp& fp) -> int {
+ return fp.significand_size;
+}
+template <typename T>
+inline auto get_significand_size(const dragonbox::decimal_fp<T>& fp) -> int {
+ return count_digits(fp.significand);
+}
+
+template <typename Char, typename OutputIt>
+constexpr auto write_significand(OutputIt out, const char* significand,
+ int significand_size) -> OutputIt {
+ return copy_str<Char>(significand, significand + significand_size, out);
+}
+template <typename Char, typename OutputIt, typename UInt>
+inline auto write_significand(OutputIt out, UInt significand,
+ int significand_size) -> OutputIt {
+ return format_decimal<Char>(out, significand, significand_size).end;
+}
+template <typename Char, typename OutputIt, typename T, typename Grouping>
+FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
+ int significand_size, int exponent,
+ const Grouping& grouping) -> OutputIt {
+ if (!grouping.separator()) {
+ out = write_significand<Char>(out, significand, significand_size);
+ return detail::fill_n(out, exponent, static_cast<Char>('0'));
+ }
+ auto buffer = memory_buffer();
+ write_significand<char>(appender(buffer), significand, significand_size);
+ detail::fill_n(appender(buffer), exponent, '0');
+ return grouping.apply(out, string_view(buffer.data(), buffer.size()));
+}
+
+template <typename Char, typename UInt,
+ FMT_ENABLE_IF(std::is_integral<UInt>::value)>
+inline auto write_significand(Char* out, UInt significand, int significand_size,
+ int integral_size, Char decimal_point) -> Char* {
+ if (!decimal_point)
+ return format_decimal(out, significand, significand_size).end;
+ out += significand_size + 1;
+ Char* end = out;
+ int floating_size = significand_size - integral_size;
+ for (int i = floating_size / 2; i > 0; --i) {
+ out -= 2;
+ copy2(out, digits2(significand % 100));
+ significand /= 100;
+ }
+ if (floating_size % 2 != 0) {
+ *--out = static_cast<Char>('0' + significand % 10);
+ significand /= 10;
+ }
+ *--out = decimal_point;
+ format_decimal(out - integral_size, significand, integral_size);
+ return end;
+}
+
+template <typename OutputIt, typename UInt, typename Char,
+ FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<OutputIt>>::value)>
+inline auto write_significand(OutputIt out, UInt significand,
+ int significand_size, int integral_size,
+ Char decimal_point) -> OutputIt {
+ // Buffer is large enough to hold digits (digits10 + 1) and a decimal point.
+ Char buffer[digits10<UInt>() + 2];
+ auto end = write_significand(buffer, significand, significand_size,
+ integral_size, decimal_point);
+ return detail::copy_str_noinline<Char>(buffer, end, out);
+}
+
+template <typename OutputIt, typename Char>
+FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand,
+ int significand_size, int integral_size,
+ Char decimal_point) -> OutputIt {
+ out = detail::copy_str_noinline<Char>(significand,
+ significand + integral_size, out);
+ if (!decimal_point) return out;
+ *out++ = decimal_point;
+ return detail::copy_str_noinline<Char>(significand + integral_size,
+ significand + significand_size, out);
+}
+
+template <typename OutputIt, typename Char, typename T, typename Grouping>
+FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand,
+ int significand_size, int integral_size,
+ Char decimal_point,
+ const Grouping& grouping) -> OutputIt {
+ if (!grouping.separator()) {
+ return write_significand(out, significand, significand_size, integral_size,
+ decimal_point);
+ }
+ auto buffer = basic_memory_buffer<Char>();
+ write_significand(buffer_appender<Char>(buffer), significand,
+ significand_size, integral_size, decimal_point);
+ grouping.apply(
+ out, basic_string_view<Char>(buffer.data(), to_unsigned(integral_size)));
+ return detail::copy_str_noinline<Char>(buffer.data() + integral_size,
+ buffer.end(), out);
+}
+
+template <typename OutputIt, typename DecimalFP, typename Char,
+ typename Grouping = digit_grouping<Char>>
+FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& fp,
+ const basic_format_specs<Char>& specs,
+ float_specs fspecs, locale_ref loc)
+ -> OutputIt {
+ auto significand = fp.significand;
+ int significand_size = get_significand_size(fp);
+ constexpr Char zero = static_cast<Char>('0');
+ auto sign = fspecs.sign;
+ size_t size = to_unsigned(significand_size) + (sign ? 1 : 0);
+ using iterator = reserve_iterator<OutputIt>;
+
+ Char decimal_point =
+ fspecs.locale ? detail::decimal_point<Char>(loc) : static_cast<Char>('.');
+
+ int output_exp = fp.exponent + significand_size - 1;
+ auto use_exp_format = [=]() {
+ if (fspecs.format == float_format::exp) return true;
+ if (fspecs.format != float_format::general) return false;
+ // Use the fixed notation if the exponent is in [exp_lower, exp_upper),
+ // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation.
+ const int exp_lower = -4, exp_upper = 16;
+ return output_exp < exp_lower ||
+ output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper);
+ };
+ if (use_exp_format()) {
+ int num_zeros = 0;
+ if (fspecs.showpoint) {
+ num_zeros = fspecs.precision - significand_size;
+ if (num_zeros < 0) num_zeros = 0;
+ size += to_unsigned(num_zeros);
+ } else if (significand_size == 1) {
+ decimal_point = Char();
+ }
+ auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp;
+ int exp_digits = 2;
+ if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3;
+
+ size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits);
+ char exp_char = fspecs.upper ? 'E' : 'e';
+ auto write = [=](iterator it) {
+ if (sign) *it++ = detail::sign<Char>(sign);
+ // Insert a decimal point after the first digit and add an exponent.
+ it = write_significand(it, significand, significand_size, 1,
+ decimal_point);
+ if (num_zeros > 0) it = detail::fill_n(it, num_zeros, zero);
+ *it++ = static_cast<Char>(exp_char);
+ return write_exponent<Char>(output_exp, it);
+ };
+ return specs.width > 0 ? write_padded<align::right>(out, specs, size, write)
+ : base_iterator(out, write(reserve(out, size)));
+ }
+
+ int exp = fp.exponent + significand_size;
+ if (fp.exponent >= 0) {
+ // 1234e5 -> 123400000[.0+]
+ size += to_unsigned(fp.exponent);
+ int num_zeros = fspecs.precision - exp;
+#ifdef FMT_FUZZ
+ if (num_zeros > 5000)
+ throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
+#endif
+ if (fspecs.showpoint) {
+ if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1;
+ if (num_zeros > 0) size += to_unsigned(num_zeros) + 1;
+ }
+ auto grouping = Grouping(loc, fspecs.locale);
+ size += to_unsigned(grouping.count_separators(significand_size));
+ return write_padded<align::right>(out, specs, size, [&](iterator it) {
+ if (sign) *it++ = detail::sign<Char>(sign);
+ it = write_significand<Char>(it, significand, significand_size,
+ fp.exponent, grouping);
+ if (!fspecs.showpoint) return it;
+ *it++ = decimal_point;
+ return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
+ });
+ } else if (exp > 0) {
+ // 1234e-2 -> 12.34[0+]
+ int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0;
+ size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
+ auto grouping = Grouping(loc, fspecs.locale);
+ size += to_unsigned(grouping.count_separators(significand_size));
+ return write_padded<align::right>(out, specs, size, [&](iterator it) {
+ if (sign) *it++ = detail::sign<Char>(sign);
+ it = write_significand(it, significand, significand_size, exp,
+ decimal_point, grouping);
+ return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it;
+ });
+ }
+ // 1234e-6 -> 0.001234
+ int num_zeros = -exp;
+ if (significand_size == 0 && fspecs.precision >= 0 &&
+ fspecs.precision < num_zeros) {
+ num_zeros = fspecs.precision;
+ }
+ bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint;
+ size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros);
+ return write_padded<align::right>(out, specs, size, [&](iterator it) {
+ if (sign) *it++ = detail::sign<Char>(sign);
+ *it++ = zero;
+ if (!pointy) return it;
+ *it++ = decimal_point;
+ it = detail::fill_n(it, num_zeros, zero);
+ return write_significand<Char>(it, significand, significand_size);
+ });
+}
+
+template <typename Char> class fallback_digit_grouping {
+ public:
+ constexpr fallback_digit_grouping(locale_ref, bool) {}
+
+ constexpr Char separator() const { return Char(); }
+
+ constexpr int count_separators(int) const { return 0; }
+
+ template <typename Out, typename C>
+ constexpr Out apply(Out out, basic_string_view<C>) const {
+ return out;
+ }
+};
+
+template <typename OutputIt, typename DecimalFP, typename Char>
+FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& fp,
+ const basic_format_specs<Char>& specs,
+ float_specs fspecs, locale_ref loc)
+ -> OutputIt {
+ if (is_constant_evaluated()) {
+ return do_write_float<OutputIt, DecimalFP, Char,
+ fallback_digit_grouping<Char>>(out, fp, specs, fspecs,
+ loc);
+ } else {
+ return do_write_float(out, fp, specs, fspecs, loc);
+ }
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+FMT_CONSTEXPR20 bool isinf(T value) {
+ if (is_constant_evaluated()) {
+#if defined(__cpp_if_constexpr)
+ if constexpr (std::numeric_limits<double>::is_iec559) {
+ auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
+ constexpr auto significand_bits =
+ dragonbox::float_info<double>::significand_bits;
+ return (bits & exponent_mask<double>()) &&
+ !(bits & ((uint64_t(1) << significand_bits) - 1));
+ }
+#endif
+ }
+ return std::isinf(value);
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+FMT_CONSTEXPR20 bool isfinite(T value) {
+ if (is_constant_evaluated()) {
+#if defined(__cpp_if_constexpr)
+ if constexpr (std::numeric_limits<double>::is_iec559) {
+ auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
+ return (bits & exponent_mask<double>()) != exponent_mask<double>();
+ }
+#endif
+ }
+ return std::isfinite(value);
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+FMT_INLINE FMT_CONSTEXPR bool signbit(T value) {
+ if (is_constant_evaluated()) {
+#ifdef __cpp_if_constexpr
+ if constexpr (std::numeric_limits<double>::is_iec559) {
+ auto bits = detail::bit_cast<uint64_t>(static_cast<double>(value));
+ return (bits & (uint64_t(1) << (num_bits<uint64_t>() - 1))) != 0;
+ }
+#endif
+ }
+ return std::signbit(value);
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(std::is_floating_point<T>::value)>
+FMT_CONSTEXPR20 auto write(OutputIt out, T value,
+ basic_format_specs<Char> specs, locale_ref loc = {})
+ -> OutputIt {
+ if (const_check(!is_supported_floating_point(value))) return out;
+ float_specs fspecs = parse_float_type_spec(specs);
+ fspecs.sign = specs.sign;
+ if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit.
+ fspecs.sign = sign::minus;
+ value = -value;
+ } else if (fspecs.sign == sign::minus) {
+ fspecs.sign = sign::none;
+ }
+
+ if (!detail::isfinite(value))
+ return write_nonfinite(out, detail::isinf(value), specs, fspecs);
+
+ if (specs.align == align::numeric && fspecs.sign) {
+ auto it = reserve(out, 1);
+ *it++ = detail::sign<Char>(fspecs.sign);
+ out = base_iterator(out, it);
+ fspecs.sign = sign::none;
+ if (specs.width != 0) --specs.width;
+ }
+
+ memory_buffer buffer;
+ if (fspecs.format == float_format::hex) {
+ if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
+ snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
+ return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
+ specs);
+ }
+ int precision = specs.precision >= 0 || specs.type == presentation_type::none
+ ? specs.precision
+ : 6;
+ if (fspecs.format == float_format::exp) {
+ if (precision == max_value<int>())
+ throw_format_error("number is too big");
+ else
+ ++precision;
+ }
+ if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
+ if (!is_fast_float<T>()) fspecs.fallback = true;
+ int exp = format_float(promote_float(value), precision, fspecs, buffer);
+ fspecs.precision = precision;
+ auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
+ return write_float(out, fp, specs, fspecs, loc);
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(is_fast_float<T>::value)>
+FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt {
+ if (is_constant_evaluated()) {
+ return write(out, value, basic_format_specs<Char>());
+ }
+
+ if (const_check(!is_supported_floating_point(value))) return out;
+
+ using floaty = conditional_t<std::is_same<T, long double>::value, double, T>;
+ using uint = typename dragonbox::float_info<floaty>::carrier_uint;
+ auto bits = bit_cast<uint>(value);
+
+ auto fspecs = float_specs();
+ if (detail::signbit(value)) {
+ fspecs.sign = sign::minus;
+ value = -value;
+ }
+
+ constexpr auto specs = basic_format_specs<Char>();
+ uint mask = exponent_mask<floaty>();
+ if ((bits & mask) == mask)
+ return write_nonfinite(out, std::isinf(value), specs, fspecs);
+
+ auto dec = dragonbox::to_decimal(static_cast<floaty>(value));
+ return write_float(out, dec, specs, fspecs, {});
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(std::is_floating_point<T>::value &&
+ !is_fast_float<T>::value)>
+inline auto write(OutputIt out, T value) -> OutputIt {
+ return write(out, value, basic_format_specs<Char>());
+}
+
+template <typename Char, typename OutputIt>
+auto write(OutputIt out, monostate, basic_format_specs<Char> = {},
+ locale_ref = {}) -> OutputIt {
+ FMT_ASSERT(false, "");
+ return out;
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out, basic_string_view<Char> value)
+ -> OutputIt {
+ auto it = reserve(out, value.size());
+ it = copy_str_noinline<Char>(value.begin(), value.end(), it);
+ return base_iterator(out, it);
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(is_string<T>::value)>
+constexpr auto write(OutputIt out, const T& value) -> OutputIt {
+ return write<Char>(out, to_string_view(value));
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(is_integral<T>::value &&
+ !std::is_same<T, bool>::value &&
+ !std::is_same<T, Char>::value)>
+FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
+ auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
+ bool negative = is_negative(value);
+ // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
+ if (negative) abs_value = ~abs_value + 1;
+ int num_digits = count_digits(abs_value);
+ auto size = (negative ? 1 : 0) + static_cast<size_t>(num_digits);
+ auto it = reserve(out, size);
+ if (auto ptr = to_pointer<Char>(it, size)) {
+ if (negative) *ptr++ = static_cast<Char>('-');
+ format_decimal<Char>(ptr, abs_value, num_digits);
+ return out;
+ }
+ if (negative) *it++ = static_cast<Char>('-');
+ it = format_decimal<Char>(it, abs_value, num_digits).end;
+ return base_iterator(out, it);
+}
+
+// FMT_ENABLE_IF() condition separated to workaround an MSVC bug.
+template <
+ typename Char, typename OutputIt, typename T,
+ bool check =
+ std::is_enum<T>::value && !std::is_same<T, Char>::value &&
+ mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value !=
+ type::custom_type,
+ FMT_ENABLE_IF(check)>
+FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt {
+ return write<Char>(
+ out, static_cast<typename std::underlying_type<T>::type>(value));
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(std::is_same<T, bool>::value)>
+FMT_CONSTEXPR auto write(OutputIt out, T value,
+ const basic_format_specs<Char>& specs = {},
+ locale_ref = {}) -> OutputIt {
+ return specs.type != presentation_type::none &&
+ specs.type != presentation_type::string
+ ? write(out, value ? 1 : 0, specs, {})
+ : write_bytes(out, value ? "true" : "false", specs);
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR auto write(OutputIt out, Char value) -> OutputIt {
+ auto it = reserve(out, 1);
+ *it++ = value;
+ return base_iterator(out, it);
+}
+
+template <typename Char, typename OutputIt>
+FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value)
+ -> OutputIt {
+ if (!value) {
+ throw_format_error("string pointer is null");
+ } else {
+ out = write(out, basic_string_view<Char>(value));
+ }
+ return out;
+}
+
+template <typename Char, typename OutputIt, typename T,
+ FMT_ENABLE_IF(std::is_same<T, void>::value)>
+auto write(OutputIt out, const T* value,
+ const basic_format_specs<Char>& specs = {}, locale_ref = {})
+ -> OutputIt {
+ check_pointer_type_spec(specs.type, error_handler());
+ return write_ptr<Char>(out, to_uintptr(value), &specs);
+}
+
+// A write overload that handles implicit conversions.
+template <typename Char, typename OutputIt, typename T,
+ typename Context = basic_format_context<OutputIt, Char>>
+FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t<
+ std::is_class<T>::value && !is_string<T>::value &&
+ !std::is_same<T, Char>::value &&
+ !std::is_same<const T&,
+ decltype(arg_mapper<Context>().map(value))>::value,
+ OutputIt> {
+ return write<Char>(out, arg_mapper<Context>().map(value));
+}
+
+template <typename Char, typename OutputIt, typename T,
+ typename Context = basic_format_context<OutputIt, Char>>
+FMT_CONSTEXPR auto write(OutputIt out, const T& value)
+ -> enable_if_t<mapped_type_constant<T, Context>::value == type::custom_type,
+ OutputIt> {
+ using formatter_type =
+ conditional_t<has_formatter<T, Context>::value,
+ typename Context::template formatter_type<T>,
+ fallback_formatter<T, Char>>;
+ auto ctx = Context(out, {}, {});
+ return formatter_type().format(value, ctx);
+}
+
+// An argument visitor that formats the argument and writes it via the output
+// iterator. It's a class and not a generic lambda for compatibility with C++11.
+template <typename Char> struct default_arg_formatter {
+ using iterator = buffer_appender<Char>;
+ using context = buffer_context<Char>;
+
+ iterator out;
+ basic_format_args<context> args;
+ locale_ref loc;
+
+ template <typename T> auto operator()(T value) -> iterator {
+ return write<Char>(out, value);
+ }
+ auto operator()(typename basic_format_arg<context>::handle h) -> iterator {
+ basic_format_parse_context<Char> parse_ctx({});
+ context format_ctx(out, args, loc);
+ h.format(parse_ctx, format_ctx);
+ return format_ctx.out();
+ }
+};
+
+template <typename Char> struct arg_formatter {
+ using iterator = buffer_appender<Char>;
+ using context = buffer_context<Char>;
+
+ iterator out;
+ const basic_format_specs<Char>& specs;
+ locale_ref locale;
+
+ template <typename T>
+ FMT_CONSTEXPR FMT_INLINE auto operator()(T value) -> iterator {
+ return detail::write(out, value, specs, locale);
+ }
+ auto operator()(typename basic_format_arg<context>::handle) -> iterator {
+ // User-defined types are handled separately because they require access
+ // to the parse context.
+ return out;
+ }
+};
+
+template <typename Char> struct custom_formatter {
+ basic_format_parse_context<Char>& parse_ctx;
+ buffer_context<Char>& ctx;
+
+ void operator()(
+ typename basic_format_arg<buffer_context<Char>>::handle h) const {
+ h.format(parse_ctx, ctx);
+ }
+ template <typename T> void operator()(T) const {}
+};
+
+template <typename T>
+using is_integer =
+ bool_constant<is_integral<T>::value && !std::is_same<T, bool>::value &&
+ !std::is_same<T, char>::value &&
+ !std::is_same<T, wchar_t>::value>;
+
+template <typename ErrorHandler> class width_checker {
+ public:
+ explicit FMT_CONSTEXPR width_checker(ErrorHandler& eh) : handler_(eh) {}
+
+ template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
+ FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
+ if (is_negative(value)) handler_.on_error("negative width");
+ return static_cast<unsigned long long>(value);
+ }
+
+ template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
+ FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
+ handler_.on_error("width is not integer");
+ return 0;
+ }
+
+ private:
+ ErrorHandler& handler_;
+};
+
+template <typename ErrorHandler> class precision_checker {
+ public:
+ explicit FMT_CONSTEXPR precision_checker(ErrorHandler& eh) : handler_(eh) {}
+
+ template <typename T, FMT_ENABLE_IF(is_integer<T>::value)>
+ FMT_CONSTEXPR auto operator()(T value) -> unsigned long long {
+ if (is_negative(value)) handler_.on_error("negative precision");
+ return static_cast<unsigned long long>(value);
+ }
+
+ template <typename T, FMT_ENABLE_IF(!is_integer<T>::value)>
+ FMT_CONSTEXPR auto operator()(T) -> unsigned long long {
+ handler_.on_error("precision is not integer");
+ return 0;
+ }
+
+ private:
+ ErrorHandler& handler_;
+};
+
+template <template <typename> class Handler, typename FormatArg,
+ typename ErrorHandler>
+FMT_CONSTEXPR auto get_dynamic_spec(FormatArg arg, ErrorHandler eh) -> int {
+ unsigned long long value = visit_format_arg(Handler<ErrorHandler>(eh), arg);
+ if (value > to_unsigned(max_value<int>())) eh.on_error("number is too big");
+ return static_cast<int>(value);
+}
+
+template <typename Context, typename ID>
+FMT_CONSTEXPR auto get_arg(Context& ctx, ID id) ->
+ typename Context::format_arg {
+ auto arg = ctx.arg(id);
+ if (!arg) ctx.on_error("argument not found");
+ return arg;
+}
+
+// The standard format specifier handler with checking.
+template <typename Char> class specs_handler : public specs_setter<Char> {
+ private:
+ basic_format_parse_context<Char>& parse_context_;
+ buffer_context<Char>& context_;
+
+ // This is only needed for compatibility with gcc 4.4.
+ using format_arg = basic_format_arg<buffer_context<Char>>;
+
+ FMT_CONSTEXPR auto get_arg(auto_id) -> format_arg {
+ return detail::get_arg(context_, parse_context_.next_arg_id());
+ }
+
+ FMT_CONSTEXPR auto get_arg(int arg_id) -> format_arg {
+ parse_context_.check_arg_id(arg_id);
+ return detail::get_arg(context_, arg_id);
+ }
+
+ FMT_CONSTEXPR auto get_arg(basic_string_view<Char> arg_id) -> format_arg {
+ parse_context_.check_arg_id(arg_id);
+ return detail::get_arg(context_, arg_id);
+ }
+
+ public:
+ FMT_CONSTEXPR specs_handler(basic_format_specs<Char>& specs,
+ basic_format_parse_context<Char>& parse_ctx,
+ buffer_context<Char>& ctx)
+ : specs_setter<Char>(specs), parse_context_(parse_ctx), context_(ctx) {}
+
+ template <typename Id> FMT_CONSTEXPR void on_dynamic_width(Id arg_id) {
+ this->specs_.width = get_dynamic_spec<width_checker>(
+ get_arg(arg_id), context_.error_handler());
+ }
+
+ template <typename Id> FMT_CONSTEXPR void on_dynamic_precision(Id arg_id) {
+ this->specs_.precision = get_dynamic_spec<precision_checker>(
+ get_arg(arg_id), context_.error_handler());
+ }
+
+ void on_error(const char* message) { context_.on_error(message); }
+};
+
+template <template <typename> class Handler, typename Context>
+FMT_CONSTEXPR void handle_dynamic_spec(int& value,
+ arg_ref<typename Context::char_type> ref,
+ Context& ctx) {
+ switch (ref.kind) {
+ case arg_id_kind::none:
+ break;
+ case arg_id_kind::index:
+ value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
+ ctx.error_handler());
+ break;
+ case arg_id_kind::name:
+ value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
+ ctx.error_handler());
+ break;
+ }
+}
+
+#define FMT_STRING_IMPL(s, base, explicit) \
+ [] { \
+ /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \
+ /* Use a macro-like name to avoid shadowing warnings. */ \
+ struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \
+ using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
+ FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \
+ operator fmt::basic_string_view<char_type>() const { \
+ return fmt::detail_exported::compile_string_to_view<char_type>(s); \
+ } \
+ }; \
+ return FMT_COMPILE_STRING(); \
+ }()
+
+/**
+ \rst
+ Constructs a compile-time format string from a string literal *s*.
+
+ **Example**::
+
+ // A compile-time error because 'd' is an invalid specifier for strings.
+ std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
+ \endrst
+ */
+#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, )
+
+#if FMT_USE_USER_DEFINED_LITERALS
+template <typename Char> struct udl_formatter {
+ basic_string_view<Char> str;
+
+ template <typename... T>
+ auto operator()(T&&... args) const -> std::basic_string<Char> {
+ return vformat(str, fmt::make_args_checked<T...>(str, args...));
+ }
+};
+
+# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+template <typename T, typename Char, size_t N,
+ fmt::detail_exported::fixed_string<Char, N> Str>
+struct statically_named_arg : view {
+ static constexpr auto name = Str.data;
+
+ const T& value;
+ statically_named_arg(const T& v) : value(v) {}
+};
+
+template <typename T, typename Char, size_t N,
+ fmt::detail_exported::fixed_string<Char, N> Str>
+struct is_named_arg<statically_named_arg<T, Char, N, Str>> : std::true_type {};
+
+template <typename T, typename Char, size_t N,
+ fmt::detail_exported::fixed_string<Char, N> Str>
+struct is_statically_named_arg<statically_named_arg<T, Char, N, Str>>
+ : std::true_type {};
+
+template <typename Char, size_t N,
+ fmt::detail_exported::fixed_string<Char, N> Str>
+struct udl_arg {
+ template <typename T> auto operator=(T&& value) const {
+ return statically_named_arg<T, Char, N, Str>(std::forward<T>(value));
+ }
+};
+# else
+template <typename Char> struct udl_arg {
+ const Char* str;
+
+ template <typename T> auto operator=(T&& value) const -> named_arg<Char, T> {
+ return {str, std::forward<T>(value)};
+ }
+};
+# endif
+#endif // FMT_USE_USER_DEFINED_LITERALS
+
+template <typename Locale, typename Char>
+auto vformat(const Locale& loc, basic_string_view<Char> format_str,
+ basic_format_args<buffer_context<type_identity_t<Char>>> args)
+ -> std::basic_string<Char> {
+ basic_memory_buffer<Char> buffer;
+ detail::vformat_to(buffer, format_str, args, detail::locale_ref(loc));
+ return {buffer.data(), buffer.size()};
+}
+
+using format_func = void (*)(detail::buffer<char>&, int, const char*);
+
+FMT_API void format_error_code(buffer<char>& out, int error_code,
+ string_view message) FMT_NOEXCEPT;
+
+FMT_API void report_error(format_func func, int error_code,
+ const char* message) FMT_NOEXCEPT;
+FMT_END_DETAIL_NAMESPACE
+
+FMT_API auto vsystem_error(int error_code, string_view format_str,
+ format_args args) -> std::system_error;
+
+/**
+ \rst
+ Constructs :class:`std::system_error` with a message formatted with
+ ``fmt::format(fmt, args...)``.
+ *error_code* is a system error code as given by ``errno``.
+
+ **Example**::
+
+ // This throws std::system_error with the description
+ // cannot open file 'madeup': No such file or directory
+ // or similar (system message may vary).
+ const char* filename = "madeup";
+ std::FILE* file = std::fopen(filename, "r");
+ if (!file)
+ throw fmt::system_error(errno, "cannot open file '{}'", filename);
+ \endrst
+*/
+template <typename... T>
+auto system_error(int error_code, format_string<T...> fmt, T&&... args)
+ -> std::system_error {
+ return vsystem_error(error_code, fmt, fmt::make_format_args(args...));
+}
+
+/**
+ \rst
+ Formats an error message for an error returned by an operating system or a
+ language runtime, for example a file opening error, and writes it to *out*.
+ The format is the same as the one used by ``std::system_error(ec, message)``
+ where ``ec`` is ``std::error_code(error_code, std::generic_category()})``.
+ It is implementation-defined but normally looks like:
+
+ .. parsed-literal::
+ *<message>*: *<system-message>*
+
+ where *<message>* is the passed message and *<system-message>* is the system
+ message corresponding to the error code.
+ *error_code* is a system error code as given by ``errno``.
+ \endrst
+ */
+FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
+ const char* message) FMT_NOEXCEPT;
+
+// Reports a system error without throwing an exception.
+// Can be used to report errors from destructors.
+FMT_API void report_system_error(int error_code,
+ const char* message) FMT_NOEXCEPT;
+
+/** Fast integer formatter. */
+class format_int {
+ private:
+ // Buffer should be large enough to hold all digits (digits10 + 1),
+ // a sign and a null character.
+ enum { buffer_size = std::numeric_limits<unsigned long long>::digits10 + 3 };
+ mutable char buffer_[buffer_size];
+ char* str_;
+
+ template <typename UInt> auto format_unsigned(UInt value) -> char* {
+ auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
+ return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
+ }
+
+ template <typename Int> auto format_signed(Int value) -> char* {
+ auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
+ bool negative = value < 0;
+ if (negative) abs_value = 0 - abs_value;
+ auto begin = format_unsigned(abs_value);
+ if (negative) *--begin = '-';
+ return begin;
+ }
+
+ public:
+ explicit format_int(int value) : str_(format_signed(value)) {}
+ explicit format_int(long value) : str_(format_signed(value)) {}
+ explicit format_int(long long value) : str_(format_signed(value)) {}
+ explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
+ explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
+ explicit format_int(unsigned long long value)
+ : str_(format_unsigned(value)) {}
+
+ /** Returns the number of characters written to the output buffer. */
+ auto size() const -> size_t {
+ return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
+ }
+
+ /**
+ Returns a pointer to the output buffer content. No terminating null
+ character is appended.
+ */
+ auto data() const -> const char* { return str_; }
+
+ /**
+ Returns a pointer to the output buffer content with terminating null
+ character appended.
+ */
+ auto c_str() const -> const char* {
+ buffer_[buffer_size - 1] = '\0';
+ return str_;
+ }
+
+ /**
+ \rst
+ Returns the content of the output buffer as an ``std::string``.
+ \endrst
+ */
+ auto str() const -> std::string { return std::string(str_, size()); }
+};
+
+template <typename T, typename Char>
+template <typename FormatContext>
+FMT_CONSTEXPR FMT_INLINE auto
+formatter<T, Char,
+ enable_if_t<detail::type_constant<T, Char>::value !=
+ detail::type::custom_type>>::format(const T& val,
+ FormatContext& ctx)
+ const -> decltype(ctx.out()) {
+ if (specs_.width_ref.kind != detail::arg_id_kind::none ||
+ specs_.precision_ref.kind != detail::arg_id_kind::none) {
+ auto specs = specs_;
+ detail::handle_dynamic_spec<detail::width_checker>(specs.width,
+ specs.width_ref, ctx);
+ detail::handle_dynamic_spec<detail::precision_checker>(
+ specs.precision, specs.precision_ref, ctx);
+ return detail::write<Char>(ctx.out(), val, specs, ctx.locale());
+ }
+ return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
+}
+
+#define FMT_FORMAT_AS(Type, Base) \
+ template <typename Char> \
+ struct formatter<Type, Char> : formatter<Base, Char> { \
+ template <typename FormatContext> \
+ auto format(Type const& val, FormatContext& ctx) const \
+ -> decltype(ctx.out()) { \
+ return formatter<Base, Char>::format(static_cast<Base>(val), ctx); \
+ } \
+ }
+
+FMT_FORMAT_AS(signed char, int);
+FMT_FORMAT_AS(unsigned char, unsigned);
+FMT_FORMAT_AS(short, int);
+FMT_FORMAT_AS(unsigned short, unsigned);
+FMT_FORMAT_AS(long, long long);
+FMT_FORMAT_AS(unsigned long, unsigned long long);
+FMT_FORMAT_AS(Char*, const Char*);
+FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
+FMT_FORMAT_AS(std::nullptr_t, const void*);
+FMT_FORMAT_AS(detail::byte, unsigned char);
+FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
+
+template <typename Char>
+struct formatter<void*, Char> : formatter<const void*, Char> {
+ template <typename FormatContext>
+ auto format(void* val, FormatContext& ctx) const -> decltype(ctx.out()) {
+ return formatter<const void*, Char>::format(val, ctx);
+ }
+};
+
+template <typename Char, size_t N>
+struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
+ template <typename FormatContext>
+ FMT_CONSTEXPR auto format(const Char* val, FormatContext& ctx) const
+ -> decltype(ctx.out()) {
+ return formatter<basic_string_view<Char>, Char>::format(val, ctx);
+ }
+};
+
+// A formatter for types known only at run time such as variant alternatives.
+//
+// Usage:
+// using variant = std::variant<int, std::string>;
+// template <>
+// struct formatter<variant>: dynamic_formatter<> {
+// auto format(const variant& v, format_context& ctx) {
+// return visit([&](const auto& val) {
+// return dynamic_formatter<>::format(val, ctx);
+// }, v);
+// }
+// };
+template <typename Char = char> class dynamic_formatter {
+ private:
+ detail::dynamic_format_specs<Char> specs_;
+ const Char* format_str_;
+
+ struct null_handler : detail::error_handler {
+ void on_align(align_t) {}
+ void on_sign(sign_t) {}
+ void on_hash() {}
+ };
+
+ template <typename Context> void handle_specs(Context& ctx) {
+ detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
+ specs_.width_ref, ctx);
+ detail::handle_dynamic_spec<detail::precision_checker>(
+ specs_.precision, specs_.precision_ref, ctx);
+ }
+
+ public:
+ template <typename ParseContext>
+ FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
+ format_str_ = ctx.begin();
+ // Checks are deferred to formatting time when the argument type is known.
+ detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
+ return detail::parse_format_specs(ctx.begin(), ctx.end(), handler);
+ }
+
+ template <typename T, typename FormatContext>
+ auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
+ handle_specs(ctx);
+ detail::specs_checker<null_handler> checker(
+ null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
+ checker.on_align(specs_.align);
+ if (specs_.sign != sign::none) checker.on_sign(specs_.sign);
+ if (specs_.alt) checker.on_hash();
+ if (specs_.precision >= 0) checker.end_precision();
+ return detail::write<Char>(ctx.out(), val, specs_, ctx.locale());
+ }
+};
+
+/**
+ \rst
+ Converts ``p`` to ``const void*`` for pointer formatting.
+
+ **Example**::
+
+ auto s = fmt::format("{}", fmt::ptr(p));
+ \endrst
+ */
+template <typename T> auto ptr(T p) -> const void* {
+ static_assert(std::is_pointer<T>::value, "");
+ return detail::bit_cast<const void*>(p);
+}
+template <typename T> auto ptr(const std::unique_ptr<T>& p) -> const void* {
+ return p.get();
+}
+template <typename T> auto ptr(const std::shared_ptr<T>& p) -> const void* {
+ return p.get();
+}
+
+class bytes {
+ private:
+ string_view data_;
+ friend struct formatter<bytes>;
+
+ public:
+ explicit bytes(string_view data) : data_(data) {}
+};
+
+template <> struct formatter<bytes> {
+ private:
+ detail::dynamic_format_specs<char> specs_;
+
+ public:
+ template <typename ParseContext>
+ FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
+ using handler_type = detail::dynamic_specs_handler<ParseContext>;
+ detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
+ detail::type::string_type);
+ auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
+ detail::check_string_type_spec(specs_.type, ctx.error_handler());
+ return it;
+ }
+
+ template <typename FormatContext>
+ auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
+ detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
+ specs_.width_ref, ctx);
+ detail::handle_dynamic_spec<detail::precision_checker>(
+ specs_.precision, specs_.precision_ref, ctx);
+ return detail::write_bytes(ctx.out(), b.data_, specs_);
+ }
+};
+
+// group_digits_view is not derived from view because it copies the argument.
+template <typename T> struct group_digits_view { T value; };
+
+/**
+ \rst
+ Returns a view that formats an integer value using ',' as a locale-independent
+ thousands separator.
+
+ **Example**::
+
+ fmt::print("{}", fmt::group_digits(12345));
+ // Output: "12,345"
+ \endrst
+ */
+template <typename T> auto group_digits(T value) -> group_digits_view<T> {
+ return {value};
+}
+
+template <typename T> struct formatter<group_digits_view<T>> : formatter<T> {
+ private:
+ detail::dynamic_format_specs<char> specs_;
+
+ public:
+ template <typename ParseContext>
+ FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
+ using handler_type = detail::dynamic_specs_handler<ParseContext>;
+ detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
+ detail::type::int_type);
+ auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
+ detail::check_string_type_spec(specs_.type, ctx.error_handler());
+ return it;
+ }
+
+ template <typename FormatContext>
+ auto format(group_digits_view<T> t, FormatContext& ctx)
+ -> decltype(ctx.out()) {
+ detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
+ specs_.width_ref, ctx);
+ detail::handle_dynamic_spec<detail::precision_checker>(
+ specs_.precision, specs_.precision_ref, ctx);
+ return detail::write_int_localized(
+ ctx.out(), static_cast<detail::uint64_or_128_t<T>>(t.value), 0, specs_,
+ detail::digit_grouping<char>({"\3", ','}));
+ }
+};
+
+template <typename It, typename Sentinel, typename Char = char>
+struct join_view : detail::view {
+ It begin;
+ Sentinel end;
+ basic_string_view<Char> sep;
+
+ join_view(It b, Sentinel e, basic_string_view<Char> s)
+ : begin(b), end(e), sep(s) {}
+};
+
+template <typename It, typename Sentinel, typename Char>
+using arg_join FMT_DEPRECATED_ALIAS = join_view<It, Sentinel, Char>;
+
+template <typename It, typename Sentinel, typename Char>
+struct formatter<join_view<It, Sentinel, Char>, Char> {
+ private:
+ using value_type =
+#ifdef __cpp_lib_ranges
+ std::iter_value_t<It>;
+#else
+ typename std::iterator_traits<It>::value_type;
+#endif
+ using context = buffer_context<Char>;
+ using mapper = detail::arg_mapper<context>;
+
+ template <typename T, FMT_ENABLE_IF(has_formatter<T, context>::value)>
+ static auto map(const T& value) -> const T& {
+ return value;
+ }
+ template <typename T, FMT_ENABLE_IF(!has_formatter<T, context>::value)>
+ static auto map(const T& value) -> decltype(mapper().map(value)) {
+ return mapper().map(value);
+ }
+
+ using formatter_type =
+ conditional_t<is_formattable<value_type, Char>::value,
+ formatter<remove_cvref_t<decltype(map(
+ std::declval<const value_type&>()))>,
+ Char>,
+ detail::fallback_formatter<value_type, Char>>;
+
+ formatter_type value_formatter_;
+
+ public:
+ template <typename ParseContext>
+ FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
+ return value_formatter_.parse(ctx);
+ }
+
+ template <typename FormatContext>
+ auto format(const join_view<It, Sentinel, Char>& value, FormatContext& ctx)
+ -> decltype(ctx.out()) {
+ auto it = value.begin;
+ auto out = ctx.out();
+ if (it != value.end) {
+ out = value_formatter_.format(map(*it), ctx);
+ ++it;
+ while (it != value.end) {
+ out = detail::copy_str<Char>(value.sep.begin(), value.sep.end(), out);
+ ctx.advance_to(out);
+ out = value_formatter_.format(map(*it), ctx);
+ ++it;
+ }
+ }
+ return out;
+ }
+};
+
+/**
+ Returns a view that formats the iterator range `[begin, end)` with elements
+ separated by `sep`.
+ */
+template <typename It, typename Sentinel>
+auto join(It begin, Sentinel end, string_view sep) -> join_view<It, Sentinel> {
+ return {begin, end, sep};
+}
+
+/**
+ \rst
+ Returns a view that formats `range` with elements separated by `sep`.
+
+ **Example**::
+
+ std::vector<int> v = {1, 2, 3};
+ fmt::print("{}", fmt::join(v, ", "));
+ // Output: "1, 2, 3"
+
+ ``fmt::join`` applies passed format specifiers to the range elements::
+
+ fmt::print("{:02}", fmt::join(v, ", "));
+ // Output: "01, 02, 03"
+ \endrst
+ */
+template <typename Range>
+auto join(Range&& range, string_view sep)
+ -> join_view<detail::iterator_t<Range>, detail::sentinel_t<Range>> {
+ return join(std::begin(range), std::end(range), sep);
+}
+
+/**
+ \rst
+ Converts *value* to ``std::string`` using the default format for type *T*.
+
+ **Example**::
+
+ #include <fmt/format.h>
+
+ std::string answer = fmt::to_string(42);
+ \endrst
+ */
+template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
+inline auto to_string(const T& value) -> std::string {
+ auto result = std::string();
+ detail::write<char>(std::back_inserter(result), value);
+ return result;
+}
+
+template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
+FMT_NODISCARD inline auto to_string(T value) -> std::string {
+ // The buffer should be large enough to store the number including the sign
+ // or "false" for bool.
+ constexpr int max_size = detail::digits10<T>() + 2;
+ char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
+ char* begin = buffer;
+ return std::string(begin, detail::write<char>(begin, value));
+}
+
+template <typename Char, size_t SIZE>
+FMT_NODISCARD auto to_string(const basic_memory_buffer<Char, SIZE>& buf)
+ -> std::basic_string<Char> {
+ auto size = buf.size();
+ detail::assume(size < std::basic_string<Char>().max_size());
+ return std::basic_string<Char>(buf.data(), size);
+}
+
+FMT_BEGIN_DETAIL_NAMESPACE
+
+template <typename Char>
+void vformat_to(
+ buffer<Char>& buf, basic_string_view<Char> fmt,
+ basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args,
+ locale_ref loc) {
+ // workaround for msvc bug regarding name-lookup in module
+ // link names into function scope
+ using detail::arg_formatter;
+ using detail::buffer_appender;
+ using detail::custom_formatter;
+ using detail::default_arg_formatter;
+ using detail::get_arg;
+ using detail::locale_ref;
+ using detail::parse_format_specs;
+ using detail::specs_checker;
+ using detail::specs_handler;
+ using detail::to_unsigned;
+ using detail::type;
+ using detail::write;
+ auto out = buffer_appender<Char>(buf);
+ if (fmt.size() == 2 && equal2(fmt.data(), "{}")) {
+ auto arg = args.get(0);
+ if (!arg) error_handler().on_error("argument not found");
+ visit_format_arg(default_arg_formatter<Char>{out, args, loc}, arg);
+ return;
+ }
+
+ struct format_handler : error_handler {
+ basic_format_parse_context<Char> parse_context;
+ buffer_context<Char> context;
+
+ format_handler(buffer_appender<Char> out, basic_string_view<Char> str,
+ basic_format_args<buffer_context<Char>> args, locale_ref loc)
+ : parse_context(str), context(out, args, loc) {}
+
+ void on_text(const Char* begin, const Char* end) {
+ auto text = basic_string_view<Char>(begin, to_unsigned(end - begin));
+ context.advance_to(write<Char>(context.out(), text));
+ }
+
+ FMT_CONSTEXPR auto on_arg_id() -> int {
+ return parse_context.next_arg_id();
+ }
+ FMT_CONSTEXPR auto on_arg_id(int id) -> int {
+ return parse_context.check_arg_id(id), id;
+ }
+ FMT_CONSTEXPR auto on_arg_id(basic_string_view<Char> id) -> int {
+ int arg_id = context.arg_id(id);
+ if (arg_id < 0) on_error("argument not found");
+ return arg_id;
+ }
+
+ FMT_INLINE void on_replacement_field(int id, const Char*) {
+ auto arg = get_arg(context, id);
+ context.advance_to(visit_format_arg(
+ default_arg_formatter<Char>{context.out(), context.args(),
+ context.locale()},
+ arg));
+ }
+
+ auto on_format_specs(int id, const Char* begin, const Char* end)
+ -> const Char* {
+ auto arg = get_arg(context, id);
+ if (arg.type() == type::custom_type) {
+ parse_context.advance_to(parse_context.begin() +
+ (begin - &*parse_context.begin()));
+ visit_format_arg(custom_formatter<Char>{parse_context, context}, arg);
+ return parse_context.begin();
+ }
+ auto specs = basic_format_specs<Char>();
+ specs_checker<specs_handler<Char>> handler(
+ specs_handler<Char>(specs, parse_context, context), arg.type());
+ begin = parse_format_specs(begin, end, handler);
+ if (begin == end || *begin != '}')
+ on_error("missing '}' in format string");
+ auto f = arg_formatter<Char>{context.out(), specs, context.locale()};
+ context.advance_to(visit_format_arg(f, arg));
+ return begin;
+ }
+ };
+ detail::parse_format_string<false>(fmt, format_handler(out, fmt, args, loc));
+}
+
+#ifndef FMT_HEADER_ONLY
+extern template FMT_API auto thousands_sep_impl<char>(locale_ref)
+ -> thousands_sep_result<char>;
+extern template FMT_API auto thousands_sep_impl<wchar_t>(locale_ref)
+ -> thousands_sep_result<wchar_t>;
+extern template FMT_API auto decimal_point_impl(locale_ref) -> char;
+extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t;
+extern template auto format_float<double>(double value, int precision,
+ float_specs specs, buffer<char>& buf)
+ -> int;
+extern template auto format_float<long double>(long double value, int precision,
+ float_specs specs,
+ buffer<char>& buf) -> int;
+void snprintf_float(float, int, float_specs, buffer<char>&) = delete;
+extern template auto snprintf_float<double>(double value, int precision,
+ float_specs specs,
+ buffer<char>& buf) -> int;
+extern template auto snprintf_float<long double>(long double value,
+ int precision,
+ float_specs specs,
+ buffer<char>& buf) -> int;
+#endif // FMT_HEADER_ONLY
+
+FMT_END_DETAIL_NAMESPACE
+
+#if FMT_USE_USER_DEFINED_LITERALS
+inline namespace literals {
+/**
+ \rst
+ User-defined literal equivalent of :func:`fmt::arg`.
+
+ **Example**::
+
+ using namespace fmt::literals;
+ fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
+ \endrst
+ */
+# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS
+template <detail_exported::fixed_string Str>
+constexpr auto operator""_a()
+ -> detail::udl_arg<remove_cvref_t<decltype(Str.data[0])>,
+ sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> {
+ return {};
+}
+# else
+constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg<char> {
+ return {s};
+}
+# endif
+
+// DEPRECATED!
+// User-defined literal equivalent of fmt::format.
+FMT_DEPRECATED constexpr auto operator"" _format(const char* s, size_t n)
+ -> detail::udl_formatter<char> {
+ return {{s, n}};
+}
+} // namespace literals
+#endif // FMT_USE_USER_DEFINED_LITERALS
+
+template <typename Locale, FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
+inline auto vformat(const Locale& loc, string_view fmt, format_args args)
+ -> std::string {
+ return detail::vformat(loc, fmt, args);
+}
+
+template <typename Locale, typename... T,
+ FMT_ENABLE_IF(detail::is_locale<Locale>::value)>
+inline auto format(const Locale& loc, format_string<T...> fmt, T&&... args)
+ -> std::string {
+ return vformat(loc, string_view(fmt), fmt::make_format_args(args...));
+}
+
+template <typename... T, size_t SIZE, typename Allocator>
+FMT_DEPRECATED auto format_to(basic_memory_buffer<char, SIZE, Allocator>& buf,
+ format_string<T...> fmt, T&&... args)
+ -> appender {
+ detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...));
+ return appender(buf);
+}
+
+template <typename OutputIt, typename Locale,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
+ detail::is_locale<Locale>::value)>
+auto vformat_to(OutputIt out, const Locale& loc, string_view fmt,
+ format_args args) -> OutputIt {
+ using detail::get_buffer;
+ auto&& buf = get_buffer<char>(out);
+ detail::vformat_to(buf, fmt, args, detail::locale_ref(loc));
+ return detail::get_iterator(buf);
+}
+
+template <typename OutputIt, typename Locale, typename... T,
+ FMT_ENABLE_IF(detail::is_output_iterator<OutputIt, char>::value&&
+ detail::is_locale<Locale>::value)>
+FMT_INLINE auto format_to(OutputIt out, const Locale& loc,
+ format_string<T...> fmt, T&&... args) -> OutputIt {
+ return vformat_to(out, loc, fmt, fmt::make_format_args(args...));
+}
+
+FMT_MODULE_EXPORT_END
+FMT_END_NAMESPACE
+
+#ifdef FMT_DEPRECATED_INCLUDE_XCHAR
+# include "xchar.h"
+#endif
+
+#ifdef FMT_HEADER_ONLY
+# define FMT_FUNC inline
+# include "format-inl.h"
+#else
+# define FMT_FUNC
+#endif
+
+#endif // FMT_FORMAT_H_
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 4f78fbfc9e7..24cc5735c96 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1480,7 +1480,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
elif device_type == 'HIP':
import sys
- col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1')
+ col.label(text="Requires discrete AMD GPU with Vega architecture", icon='BLANK1')
if sys.platform[:3] == "win":
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
elif device_type == 'METAL':
diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake
index 0f2e1b50434..e69e31f8e52 100644
--- a/intern/cycles/cmake/macros.cmake
+++ b/intern/cycles/cmake/macros.cmake
@@ -101,6 +101,7 @@ macro(cycles_target_link_libraries target)
${PNG_LIBRARIES}
${JPEG_LIBRARIES}
${TIFF_LIBRARY}
+ ${WEBP_LIBRARIES}
${OPENJPEG_LIBRARIES}
${OPENEXR_LIBRARIES}
${OPENEXR_LIBRARIES} # For circular dependencies between libs.
diff --git a/intern/cycles/device/hip/util.h b/intern/cycles/device/hip/util.h
index adb68a2d44c..4e4906171d1 100644
--- a/intern/cycles/device/hip/util.h
+++ b/intern/cycles/device/hip/util.h
@@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
- return (major > 10) || (major == 10 && minor >= 1);
+ return (major >= 9);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/hydra/curves.h b/intern/cycles/hydra/curves.h
index a1ac4a86715..1eb4a51c0db 100644
--- a/intern/cycles/hydra/curves.h
+++ b/intern/cycles/hydra/curves.h
@@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE
class HdCyclesCurves final : public HdCyclesGeometry<PXR_NS::HdBasisCurves, CCL_NS::Hair> {
public:
- HdCyclesCurves(const PXR_NS::SdfPath &rprimId
+ HdCyclesCurves(
+ const PXR_NS::SdfPath &rprimId
#if PXR_VERSION < 2102
- ,
- const PXR_NS::SdfPath &instancerId = {}
+ ,
+ const PXR_NS::SdfPath &instancerId = {}
#endif
);
~HdCyclesCurves() override;
diff --git a/intern/cycles/hydra/mesh.h b/intern/cycles/hydra/mesh.h
index e7aa2e4fa94..8ec108534a1 100644
--- a/intern/cycles/hydra/mesh.h
+++ b/intern/cycles/hydra/mesh.h
@@ -14,10 +14,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE
class HdCyclesMesh final : public HdCyclesGeometry<PXR_NS::HdMesh, CCL_NS::Mesh> {
public:
- HdCyclesMesh(const PXR_NS::SdfPath &rprimId
+ HdCyclesMesh(
+ const PXR_NS::SdfPath &rprimId
#if PXR_VERSION < 2102
- ,
- const PXR_NS::SdfPath &instancerId = {}
+ ,
+ const PXR_NS::SdfPath &instancerId = {}
#endif
);
~HdCyclesMesh() override;
diff --git a/intern/cycles/hydra/node_util.h b/intern/cycles/hydra/node_util.h
index e91f554cc45..009a4a9eb38 100644
--- a/intern/cycles/hydra/node_util.h
+++ b/intern/cycles/hydra/node_util.h
@@ -4,8 +4,8 @@
#pragma once
-#include "hydra/config.h"
#include "graph/node.h"
+#include "hydra/config.h"
#include <pxr/base/vt/value.h>
diff --git a/intern/cycles/hydra/pointcloud.h b/intern/cycles/hydra/pointcloud.h
index aa1768e807f..a014a389dcc 100644
--- a/intern/cycles/hydra/pointcloud.h
+++ b/intern/cycles/hydra/pointcloud.h
@@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE
class HdCyclesPoints final : public HdCyclesGeometry<PXR_NS::HdPoints, CCL_NS::PointCloud> {
public:
- HdCyclesPoints(const PXR_NS::SdfPath &rprimId
+ HdCyclesPoints(
+ const PXR_NS::SdfPath &rprimId
#if PXR_VERSION < 2102
- ,
- const PXR_NS::SdfPath &instancerId = {}
+ ,
+ const PXR_NS::SdfPath &instancerId = {}
#endif
);
~HdCyclesPoints() override;
diff --git a/intern/cycles/hydra/volume.h b/intern/cycles/hydra/volume.h
index 775a7cf069e..7fb5fa779b5 100644
--- a/intern/cycles/hydra/volume.h
+++ b/intern/cycles/hydra/volume.h
@@ -13,10 +13,11 @@ HDCYCLES_NAMESPACE_OPEN_SCOPE
class HdCyclesVolume final : public HdCyclesGeometry<PXR_NS::HdVolume, CCL_NS::Volume> {
public:
- HdCyclesVolume(const PXR_NS::SdfPath &rprimId
+ HdCyclesVolume(
+ const PXR_NS::SdfPath &rprimId
#if PXR_VERSION < 2102
- ,
- const PXR_NS::SdfPath &instancerId = {}
+ ,
+ const PXR_NS::SdfPath &instancerId = {}
#endif
);
~HdCyclesVolume() override;
diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h
index fb65d744a0c..33706213403 100644
--- a/intern/cycles/kernel/closure/bsdf_hair_principled.h
+++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h
@@ -220,7 +220,7 @@ ccl_device_inline void hair_attenuation(KernelGlobals kg,
ccl_private float4 *Ap)
{
/* Primary specular (R). */
- Ap[0] = make_float4(f);
+ Ap[0] = make_float4(f, f, f, f);
/* Transmission (TT). */
float3 col = sqr(1.0f - f) * T;
diff --git a/intern/cycles/kernel/device/cpu/image.h b/intern/cycles/kernel/device/cpu/image.h
index ebddc1989bd..3b714a3e580 100644
--- a/intern/cycles/kernel/device/cpu/image.h
+++ b/intern/cycles/kernel/device/cpu/image.h
@@ -31,20 +31,18 @@ ccl_device_inline float frac(float x, int *ix)
return x - (float)i;
}
-template<typename ZeroT> ccl_always_inline ZeroT zero();
-
-template<> ccl_always_inline float zero<float>()
-{
- return 0.0f;
-}
-
-template<> ccl_always_inline float4 zero<float4>()
-{
- return zero_float4();
-}
-
template<typename TexT, typename OutT = float4> struct TextureInterpolator {
+ static ccl_always_inline OutT zero()
+ {
+ if constexpr (std::is_same<OutT, float4>::value) {
+ return zero_float4();
+ }
+ else {
+ return 0.0f;
+ }
+ }
+
static ccl_always_inline float4 read(float4 r)
{
return r;
@@ -99,7 +97,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
static ccl_always_inline OutT read_clip(const TexT *data, int x, int y, int width, int height)
{
if (x < 0 || x >= width || y < 0 || y >= height) {
- return zero<OutT>();
+ return zero();
}
return read(data[y * width + x]);
}
@@ -118,7 +116,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
read_clip(const TexT *data, int x, int y, int z, int width, int height, int depth)
{
if (x < 0 || x >= width || y < 0 || y >= height || z < 0 || z >= depth) {
- return zero<OutT>();
+ return zero();
}
return read(data[x + y * width + z * width * height]);
}
@@ -221,7 +219,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP:
/* No samples are inside the clip region. */
if (ix < 0 || ix >= width || iy < 0 || iy >= height) {
- return zero<OutT>();
+ return zero();
}
break;
case EXTENSION_EXTEND:
@@ -230,7 +228,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
const TexT *data = (const TexT *)info.data;
@@ -259,7 +257,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP:
/* No linear samples are inside the clip region. */
if (ix < -1 || ix >= width || iy < -1 || iy >= height) {
- return zero<OutT>();
+ return zero();
}
nix = ix + 1;
niy = iy + 1;
@@ -272,7 +270,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
const TexT *data = (const TexT *)info.data;
@@ -311,7 +309,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP:
/* No cubic samples are inside the clip region. */
if (ix < -2 || ix > width || iy < -2 || iy > height) {
- return zero<OutT>();
+ return zero();
}
pix = ix - 1;
@@ -335,7 +333,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
const TexT *data = (const TexT *)info.data;
@@ -397,7 +395,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP:
/* No samples are inside the clip region. */
if (ix < 0 || ix >= width || iy < 0 || iy >= height || iz < 0 || iz >= depth) {
- return zero<OutT>();
+ return zero();
}
break;
case EXTENSION_EXTEND:
@@ -407,7 +405,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
const TexT *data = (const TexT *)info.data;
@@ -444,7 +442,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP:
/* No linear samples are inside the clip region. */
if (ix < -1 || ix >= width || iy < -1 || iy >= height || iz < -1 || iz >= depth) {
- return zero<OutT>();
+ return zero();
}
nix = ix + 1;
@@ -484,7 +482,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
return trilinear_lookup((const TexT *)info.data,
@@ -553,7 +551,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
case EXTENSION_CLIP: {
/* No cubic samples are inside the clip region. */
if (ix < -2 || ix > width || iy < -2 || iy > height || iz < -2 || iz > depth) {
- return zero<OutT>();
+ return zero();
}
pix = ix - 1;
@@ -599,7 +597,7 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
break;
default:
kernel_assert(0);
- return zero<OutT>();
+ return zero();
}
const int xc[4] = {pix, ix, nix, nnix};
const int yc[4] = {piy, iy, niy, nniy};
diff --git a/intern/cycles/kernel/film/accumulate.h b/intern/cycles/kernel/film/accumulate.h
index 6345430e4f4..d6a385a4bff 100644
--- a/intern/cycles/kernel/film/accumulate.h
+++ b/intern/cycles/kernel/film/accumulate.h
@@ -352,6 +352,12 @@ ccl_device_inline void kernel_accum_emission_or_background_pass(KernelGlobals kg
pass_offset = pass;
}
else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
+ /* Don't write any light passes for shadow catcher, for easier
+ * compositing back together of the combined pass. */
+ if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) {
+ return;
+ }
+
if (path_flag & PATH_RAY_SURFACE_PASS) {
/* Indirectly visible through reflection. */
const float3 diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight);
@@ -437,6 +443,12 @@ ccl_device_inline void kernel_accum_light(KernelGlobals kg,
if (kernel_data.film.light_pass_flag & PASS_ANY) {
const uint32_t path_flag = INTEGRATOR_STATE(state, shadow_path, flag);
+ /* Don't write any light passes for shadow catcher, for easier
+ * compositing back together of the combined pass. */
+ if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) {
+ return;
+ }
+
if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) {
int pass_offset = PASS_UNUSED;
diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp
index 755fbb9542b..fd559178073 100644
--- a/intern/cycles/scene/integrator.cpp
+++ b/intern/cycles/scene/integrator.cpp
@@ -109,8 +109,10 @@ NODE_DEFINE(Integrator)
SOCKET_INT(denoise_start_sample, "Start Sample to Denoise", 0);
SOCKET_BOOLEAN(use_denoise_pass_albedo, "Use Albedo Pass for Denoiser", true);
SOCKET_BOOLEAN(use_denoise_pass_normal, "Use Normal Pass for Denoiser", true);
- SOCKET_ENUM(
- denoiser_prefilter, "Denoiser Prefilter", denoiser_prefilter_enum, DENOISER_PREFILTER_ACCURATE);
+ SOCKET_ENUM(denoiser_prefilter,
+ "Denoiser Prefilter",
+ denoiser_prefilter_enum,
+ DENOISER_PREFILTER_ACCURATE);
return type;
}
diff --git a/intern/cycles/util/math_float4.h b/intern/cycles/util/math_float4.h
index 5d4da7dd30f..ae9dfe75a9c 100644
--- a/intern/cycles/util/math_float4.h
+++ b/intern/cycles/util/math_float4.h
@@ -90,13 +90,13 @@ ccl_device_inline float4 zero_float4()
#ifdef __KERNEL_SSE__
return float4(_mm_setzero_ps());
#else
- return make_float4(0.0f);
+ return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
#endif
}
ccl_device_inline float4 one_float4()
{
- return make_float4(1.0f);
+ return make_float4(1.0f, 1.0f, 1.0f, 1.0f);
}
#if !defined(__KERNEL_METAL__)
@@ -149,7 +149,7 @@ ccl_device_inline float4 operator/(const float4 &a, const float4 &b)
ccl_device_inline float4 operator+(const float4 &a, const float f)
{
- return a + make_float4(f);
+ return a + make_float4(f, f, f, f);
}
ccl_device_inline float4 operator+(const float4 &a, const float4 &b)
@@ -163,7 +163,7 @@ ccl_device_inline float4 operator+(const float4 &a, const float4 &b)
ccl_device_inline float4 operator-(const float4 &a, const float f)
{
- return a - make_float4(f);
+ return a - make_float4(f, f, f, f);
}
ccl_device_inline float4 operator-(const float4 &a, const float4 &b)
@@ -317,7 +317,7 @@ ccl_device_inline float4 reduce_add(const float4 &a)
# endif
# else
float sum = (a.x + a.y) + (a.z + a.w);
- return make_float4(sum);
+ return make_float4(sum, sum, sum, sum);
# endif
}
diff --git a/intern/cycles/util/types_float4.h b/intern/cycles/util/types_float4.h
index 0e84dfa3d64..68ba787dac0 100644
--- a/intern/cycles/util/types_float4.h
+++ b/intern/cycles/util/types_float4.h
@@ -45,7 +45,6 @@ ccl_device_inline float4 make_float4(const int4 &i);
ccl_device_inline void print_float4(const char *label, const float4 &a);
#endif /* __KERNEL_GPU__ */
-ccl_device_inline float4 make_float4(float f);
CCL_NAMESPACE_END
#endif /* __UTIL_TYPES_FLOAT4_H__ */
diff --git a/intern/cycles/util/types_float4_impl.h b/intern/cycles/util/types_float4_impl.h
index aa923eb038d..de2e7cb7061 100644
--- a/intern/cycles/util/types_float4_impl.h
+++ b/intern/cycles/util/types_float4_impl.h
@@ -89,11 +89,6 @@ ccl_device_inline void print_float4(const char *label, const float4 &a)
{
printf("%s: %.8f %.8f %.8f %.8f\n", label, (double)a.x, (double)a.y, (double)a.z, (double)a.w);
}
-#else
-ccl_device_inline float4 make_float4(float f)
-{
- return make_float4(f, f, f, f);
-}
#endif /* __KERNEL_GPU__ */
CCL_NAMESPACE_END
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 0f4b5147082..11a3c097958 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -151,6 +151,12 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
::SetWindowPos(m_hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
+ if (parentwindow) {
+ /* Release any parent capture to allow immediate interaction (T90110). */
+ ::ReleaseCapture();
+ parentwindow->lostMouseCapture();
+ }
+
/* Show the window. */
int nCmdShow;
switch (state) {
diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h
index 79b4e9d0cf6..d5f47871aff 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.h
+++ b/intern/ghost/intern/GHOST_WindowWin32.h
@@ -206,9 +206,7 @@ class GHOST_WindowWin32 : public GHOST_Window {
GHOST_TSuccess endProgressBar();
/**
- * Register a mouse capture state (should be called
- * for any real button press, controls mouse
- * capturing).
+ * Set or Release mouse capture (should be called for any real button press).
*
* \param event: Whether mouse was pressed and released,
* or an operator grabbed or ungrabbed the mouse.
@@ -216,8 +214,9 @@ class GHOST_WindowWin32 : public GHOST_Window {
void updateMouseCapture(GHOST_MouseCaptureEventWin32 event);
/**
- * Inform the window that it has lost mouse capture,
- * called in response to native window system messages.
+ * Inform the window that it has lost mouse capture, called in response to native window system
+ * messages (WA_INACTIVE, WM_CAPTURECHANGED) or if ReleaseCapture() is explicitly called (for new
+ * window creation).
*/
void lostMouseCapture();
diff --git a/intern/ghost/intern/GHOST_XrControllerModel.cpp b/intern/ghost/intern/GHOST_XrControllerModel.cpp
index 78d81651e92..5be3a8e70ad 100644
--- a/intern/ghost/intern/GHOST_XrControllerModel.cpp
+++ b/intern/ghost/intern/GHOST_XrControllerModel.cpp
@@ -234,7 +234,7 @@ static void calc_node_transforms(const tinygltf::Node &gltf_node,
{(float)dm[4], (float)dm[5], (float)dm[6], (float)dm[7]},
{(float)dm[8], (float)dm[9], (float)dm[10], (float)dm[11]},
{(float)dm[12], (float)dm[13], (float)dm[14], (float)dm[15]}};
- memcpy(r_local_transform, m, sizeof(float) * 16);
+ memcpy(r_local_transform, m, sizeof(float[4][4]));
}
else {
/* No matrix is present, so construct a matrix from the TRS values (each one is optional). */
diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp
index 28d0e4de7ff..bd1f1407185 100644
--- a/intern/itasc/WSDLSSolver.cpp
+++ b/intern/itasc/WSDLSSolver.cpp
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright 2009 Ruben Smits. */
-/** \file itasc/WSDLSSolver.cpp
+/** \file
* \ingroup intern_itasc
*/
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 4de4d2caf15..fcaab5dd752 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -177,6 +177,7 @@ static bool createGPUShader(OCIO_GPUShader &shader,
ShaderCreateInfo info("OCIO_Display");
/* Work around OpenColorIO not supporting latest GLSL yet. */
+ info.define("texture1D", "texture");
info.define("texture2D", "texture");
info.define("texture3D", "texture");
info.typedef_source("ocio_shader_shared.hh");
@@ -206,8 +207,11 @@ static bool createGPUShader(OCIO_GPUShader &shader,
/* Set LUT textures. */
int slot = TEXTURE_SLOT_LUTS_OFFSET;
for (OCIO_GPULutTexture &texture : textures.luts) {
- ImageType type = GPU_texture_dimensions(texture.texture) == 2 ? ImageType::FLOAT_2D :
- ImageType::FLOAT_3D;
+ const int dimensions = GPU_texture_dimensions(texture.texture);
+ ImageType type = (dimensions == 1) ? ImageType::FLOAT_1D :
+ (dimensions == 2) ? ImageType::FLOAT_2D :
+ ImageType::FLOAT_3D;
+
info.sampler(slot++, type, texture.sampler_name.c_str());
}
@@ -305,9 +309,9 @@ static bool addGPUUniform(OCIO_GPUTextures &textures,
return true;
}
-static bool addGPULut2D(OCIO_GPUTextures &textures,
- const GpuShaderDescRcPtr &shader_desc,
- int index)
+static bool addGPULut1D2D(OCIO_GPUTextures &textures,
+ const GpuShaderDescRcPtr &shader_desc,
+ int index)
{
const char *texture_name = nullptr;
const char *sampler_name = nullptr;
@@ -329,7 +333,15 @@ static bool addGPULut2D(OCIO_GPUTextures &textures,
GPU_R16F;
OCIO_GPULutTexture lut;
- lut.texture = GPU_texture_create_2d(texture_name, width, height, 1, format, values);
+ /* There does not appear to be an explicit way to check if a texture is 1D or 2D.
+ * It depends on more than height. So check instead by looking at the source. */
+ std::string sampler1D_name = std::string("sampler1D ") + sampler_name;
+ if (strstr(shader_desc->getShaderText(), sampler1D_name.c_str()) != nullptr) {
+ lut.texture = GPU_texture_create_1d(texture_name, width, 1, format, values);
+ }
+ else {
+ lut.texture = GPU_texture_create_2d(texture_name, width, height, 1, format, values);
+ }
if (lut.texture == nullptr) {
return false;
}
@@ -390,7 +402,7 @@ static bool createGPUTextures(OCIO_GPUTextures &textures,
}
}
for (int index = 0; index < shaderdesc_to_scene_linear->getNumTextures(); index++) {
- if (!addGPULut2D(textures, shaderdesc_to_scene_linear, index)) {
+ if (!addGPULut1D2D(textures, shaderdesc_to_scene_linear, index)) {
return false;
}
}
@@ -405,7 +417,7 @@ static bool createGPUTextures(OCIO_GPUTextures &textures,
}
}
for (int index = 0; index < shaderdesc_to_display->getNumTextures(); index++) {
- if (!addGPULut2D(textures, shaderdesc_to_display, index)) {
+ if (!addGPULut1D2D(textures, shaderdesc_to_display, index)) {
return false;
}
}
diff --git a/release/license/THIRD-PARTY-LICENSES.txt b/release/license/THIRD-PARTY-LICENSES.txt
index 933f03b5564..59f53832c9b 100644
--- a/release/license/THIRD-PARTY-LICENSES.txt
+++ b/release/license/THIRD-PARTY-LICENSES.txt
@@ -2961,6 +2961,8 @@ Copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.
** Expat; version 2.2.10 -- https://github.com/libexpat/libexpat/
Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper
Copyright (c) 2001-2019 Expat maintainers
+** {fmt}; version 8.1.1 -- https://github.com/fmtlib/fmt
+Copyright (c) 2012 - present, Victor Zverovich
** JSON for Modern C++; version 3.10.2 -- https://github.com/nlohmann/json/
Copyright (c) 2013-2021 Niels Lohmann
** Libxml2; version 2.9.10 -- http://xmlsoft.org/
diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py
index f8975d91f86..ef481a3eb19 100644
--- a/release/scripts/modules/bl_i18n_utils/settings.py
+++ b/release/scripts/modules/bl_i18n_utils/settings.py
@@ -340,7 +340,10 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"y",
"y = (Ax + B)",
# Sub-strings.
+ "all",
+ "all and invert unselected",
"and AMD Radeon Pro 21.Q4 driver or newer",
+ "and NVIDIA driver version 470 or newer",
"available with",
"brown fox",
"can't save image while rendering",
@@ -358,6 +361,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"face data",
"gimbal",
"global",
+ "glTF Settings",
"image file not found",
"image format is read-only",
"image path can't be written to",
@@ -370,8 +374,12 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"multi-res modifier",
"non-triangle face",
"normal",
+ "or AMD with macOS 12.3 or newer",
"performance impact!",
"right",
+ "selected",
+ "selected and lock unselected",
+ "selected and unlock unselected",
"the lazy dog",
"to the top level of the tree",
"unable to load movie clip",
@@ -380,6 +388,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = {
"unknown error reading file",
"unknown error stating file",
"unknown error writing file",
+ "unselected",
"unsupported font format",
"unsupported format",
"unsupported image format",
diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
index 144b7d09422..c0e065bf050 100644
--- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
+++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py
@@ -104,6 +104,7 @@ class SpellChecker:
"builtin", "builtins",
"bytecode",
"chunksize",
+ "codebase",
"customdata",
"dataset", "datasets",
"de",
@@ -123,6 +124,7 @@ class SpellChecker:
"filepath", "filepaths",
"forcefield", "forcefields",
"framerange",
+ "frontmost",
"fulldome", "fulldomes",
"fullscreen",
"gamepad",
diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py
index 4b10c29346e..1cd9cf9c649 100644
--- a/release/scripts/modules/rna_manual_reference.py
+++ b/release/scripts/modules/rna_manual_reference.py
@@ -344,7 +344,6 @@ url_manual_mapping = (
("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"),
("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"),
("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"),
- ("bpy.types.spaceoutliner.use_filter_lib_override*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override"),
("bpy.types.spaceoutliner.use_filter_object_empty*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-empty"),
("bpy.types.spaceoutliner.use_filter_object_light*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-light"),
("bpy.types.spacesequenceeditor.proxy_render_size*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"),
diff --git a/release/scripts/presets/keyconfig/Blender.py b/release/scripts/presets/keyconfig/Blender.py
index 8f9bea82358..7ce9a5650bd 100644
--- a/release/scripts/presets/keyconfig/Blender.py
+++ b/release/scripts/presets/keyconfig/Blender.py
@@ -87,6 +87,16 @@ class Prefs(bpy.types.KeyConfigPreferences):
)
# Experimental: only show with developer extras, see: T96544.
+ use_tweak_select_passthrough: BoolProperty(
+ name="Tweak Select: Mouse Select & Move",
+ description=(
+ "The tweak tool is activated immediately instead of placing the cursor. "
+ "This is an experimental preference and may be removed"
+ ),
+ default=False,
+ update=update_fn,
+ )
+ # Experimental: only show with developer extras, see: T96544.
use_tweak_tool_lmb_interaction: BoolProperty(
name="Tweak Tool: Left Mouse Select & Move",
description=(
@@ -283,6 +293,9 @@ class Prefs(bpy.types.KeyConfigPreferences):
row = sub.row()
row.prop(self, "use_select_all_toggle")
+ if show_developer_ui:
+ row = sub.row()
+ row.prop(self, "use_tweak_select_passthrough")
if show_developer_ui and (not is_select_left):
row = sub.row()
row.prop(self, "use_tweak_tool_lmb_interaction")
@@ -340,6 +353,7 @@ def load():
use_gizmo_drag=(is_select_left and kc_prefs.gizmo_action == 'DRAG'),
use_fallback_tool=True,
use_fallback_tool_rmb=(False if is_select_left else kc_prefs.rmb_action == 'FALLBACK_TOOL'),
+ use_tweak_select_passthrough=(show_developer_ui and kc_prefs.use_tweak_select_passthrough),
use_tweak_tool_lmb_interaction=(
False if is_select_left else
(show_developer_ui and kc_prefs.use_tweak_tool_lmb_interaction)
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index ae112ee8054..78039abcc54 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -31,6 +31,7 @@ class Params:
"context_menu_event",
"cursor_set_event",
"cursor_tweak_event",
+ "use_tweak_select_passthrough",
"use_tweak_tool_lmb_interaction",
"use_mouse_emulate_3_button",
@@ -103,6 +104,7 @@ class Params:
use_gizmo_drag=True,
use_fallback_tool=False,
use_fallback_tool_rmb=False,
+ use_tweak_select_passthrough=False,
use_tweak_tool_lmb_interaction=False,
use_v3d_tab_menu=False,
use_v3d_shade_ex_pie=False,
@@ -189,6 +191,8 @@ class Params:
self.use_file_single_click = use_file_single_click
+ self.use_tweak_select_passthrough = use_tweak_select_passthrough
+
self.use_fallback_tool = use_fallback_tool
self.use_fallback_tool_rmb = use_fallback_tool_rmb
@@ -446,7 +450,7 @@ def _template_items_change_frame(params):
# Tool System Templates
-def _template_items_tool_select(params, operator, cursor_operator, fallback, *, extend):
+def _template_items_tool_select(params, operator, cursor_operator, fallback):
if params.select_mouse == 'LEFTMOUSE':
# By default use 'PRESS' for immediate select without quick delay.
# Fallback key-maps 'CLICK' since 'PRESS' events passes through (allowing either click or drag).
@@ -458,7 +462,7 @@ def _template_items_tool_select(params, operator, cursor_operator, fallback, *,
(operator, {"type": 'LEFTMOUSE', "value": 'CLICK' if fallback else 'PRESS'},
{"properties": [("deselect_all", True)]}),
(operator, {"type": 'LEFTMOUSE', "value": 'CLICK' if fallback else 'PRESS', "shift": True},
- {"properties": [(extend, True)]}),
+ {"properties": [("toggle", True)]}),
]
else:
# Experimental support for LMB interaction for the tweak tool.
@@ -1185,7 +1189,12 @@ def km_uv_editor(params):
items.extend([
# Selection modes.
*_template_items_uv_select_mode(params),
- *_template_uv_select(type=params.select_mouse, value=params.select_mouse_value_fallback, legacy=params.legacy),
+ *_template_uv_select(
+ type=params.select_mouse,
+ value=params.select_mouse_value_fallback,
+ select_passthrough=params.use_tweak_select_passthrough,
+ legacy=params.legacy,
+ ),
("uv.mark_seam", {"type": 'E', "value": 'PRESS', "ctrl": True}, None),
("uv.select_loop",
{"type": params.select_mouse, "value": params.select_mouse_value, "alt": True}, None),
@@ -1513,6 +1522,7 @@ def km_view3d(params):
type=params.select_mouse,
value=params.select_mouse_value_fallback,
legacy=params.legacy,
+ select_passthrough=params.use_tweak_select_passthrough,
),
op_tool_optional(
("view3d.select_box", {"type": 'B', "value": 'PRESS'}, None),
@@ -4677,7 +4687,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal
return items
-def _template_view3d_select(*, type, value, legacy, exclude_mod=None):
+def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
# as a tool key-map with RMB-select and `use_fallback_tool_rmb` is enabled. See T92467.
return [(
@@ -4685,7 +4695,8 @@ def _template_view3d_select(*, type, value, legacy, exclude_mod=None):
{"type": type, "value": value, **{m: True for m in mods}},
{"properties": [(c, True) for c in props]},
) for props, mods in (
- (("deselect_all",) if not legacy else (), ()),
+ ((("deselect_all", "select_passthrough") if select_passthrough else
+ ("deselect_all",)) if not legacy else (), ()),
(("toggle",), ("shift",)),
(("center", "object"), ("ctrl",)),
(("enumerate",), ("alt",)),
@@ -4711,10 +4722,13 @@ def _template_view3d_gpencil_select(*, type, value, legacy, use_select_mouse=Tru
]
-def _template_uv_select(*, type, value, legacy):
+def _template_uv_select(*, type, value, select_passthrough, legacy):
return [
("uv.select", {"type": type, "value": value},
- {"properties": [("deselect_all", not legacy)]}),
+ {"properties": [
+ *((("deselect_all", True),) if not legacy else ()),
+ *((("select_passthrough", True),) if select_passthrough else ()),
+ ]}),
("uv.select", {"type": type, "value": value, "shift": True},
{"properties": [("toggle", True)]}),
]
@@ -6306,9 +6320,13 @@ def km_image_editor_tool_uv_select(params, *, fallback):
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
- params, "uv.select", "uv.cursor_set", fallback, extend="toggle")),
+ params, "uv.select", "uv.cursor_set", fallback)),
*([] if (not params.use_fallback_tool_rmb) else _template_uv_select(
- type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)),
+ type=params.select_mouse,
+ value=params.select_mouse_value,
+ select_passthrough=params.use_tweak_select_passthrough,
+ legacy=params.legacy,
+ )),
]},
)
@@ -6513,9 +6531,14 @@ def km_3d_view_tool_select(params, *, fallback):
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
- params, "view3d.select", "view3d.cursor3d", fallback, extend="toggle")),
+ params, "view3d.select", "view3d.cursor3d", fallback)),
*([] if (not params.use_fallback_tool_rmb) else _template_view3d_select(
- type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy, exclude_mod="ctrl")),
+ type=params.select_mouse,
+ value=params.select_mouse_value,
+ legacy=params.legacy,
+ select_passthrough=params.use_tweak_select_passthrough,
+ exclude_mod="ctrl",
+ )),
]},
)
@@ -7424,7 +7447,7 @@ def km_3d_view_tool_edit_gpencil_select(params, *, fallback):
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
- params, "gpencil.select", "view3d.cursor3d", fallback, extend="toggle")),
+ params, "gpencil.select", "view3d.cursor3d", fallback)),
*([] if (not params.use_fallback_tool_rmb) else _template_view3d_gpencil_select(
type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)),
]},
@@ -7562,7 +7585,7 @@ def km_3d_view_tool_sculpt_gpencil_select(params):
return (
"3D View Tool: Sculpt Gpencil, Tweak",
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
- {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", False, extend="toggle")},
+ {"items": _template_items_tool_select(params, "gpencil.select", "view3d.cursor3d", False)},
)
@@ -7602,7 +7625,7 @@ def km_sequencer_editor_tool_generic_select(params, *, fallback):
{"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'},
{"items": [
*([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select(
- params, "sequencer.select", "sequencer.cursor_set", fallback, extend="toggle")),
+ params, "sequencer.select", "sequencer.cursor_set", fallback)),
*([] if (not params.use_fallback_tool_rmb) else _template_sequencer_preview_select(
type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)),
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 947a7e5c7a7..d5a9887f551 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -361,6 +361,10 @@ class GPENCIL_UL_annotation_layer(UIList):
split.prop(gpl, "info", text="", emboss=False)
row = layout.row(align=True)
+
+ icon_xray = "XRAY" if gpl.show_in_front else "FACESEL"
+ row.prop(gpl, "show_in_front", text="", icon=icon_xray, emboss=False)
+
row.prop(gpl, "annotation_hide", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
diff --git a/release/scripts/startup/bl_ui/space_outliner.py b/release/scripts/startup/bl_ui/space_outliner.py
index 9d3f20ce4a4..bbe165b9286 100644
--- a/release/scripts/startup/bl_ui/space_outliner.py
+++ b/release/scripts/startup/bl_ui/space_outliner.py
@@ -442,15 +442,6 @@ class OUTLINER_PT_filter(Panel):
row.label(icon='BLANK1')
row.prop(space, "use_filter_object_others", text="Others")
- if bpy.data.libraries:
- col.separator()
- row = col.row()
- row.label(icon='LIBRARY_DATA_OVERRIDE')
- row.prop(space, "use_filter_lib_override", text="Library Overrides")
- row = col.row()
- row.label(icon='LIBRARY_DATA_OVERRIDE')
- row.prop(space, "use_filter_lib_override_system", text="System Overrides")
-
classes = (
OUTLINER_HT_header,
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 2533c993b9a..2eff8ca8cf6 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -386,8 +386,8 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa
col.prop(edit, "use_duplicate_curve", text="Curve")
# col.prop(edit, "use_duplicate_fcurve", text="F-Curve") # Not implemented.
col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil")
- if hasattr(edit, "use_duplicate_hair"):
- col.prop(edit, "use_duplicate_hair", text="Hair")
+ if hasattr(edit, "use_duplicate_curves"):
+ col.prop(edit, "use_duplicate_curves", text="Curves")
col = flow.column()
col.prop(edit, "use_duplicate_lattice", text="Lattice")
@@ -2260,6 +2260,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
self._draw_items(
context, (
({"property": "use_sculpt_tools_tilt"}, "T82877"),
+ ({"property": "use_select_nearest_on_first_click"}, "T96752"),
({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")),
({"property": "use_override_templates"}, ("T73318", "Milestone 4")),
({"property": "use_named_attribute_nodes"}, ("T91742")),
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 57e8e6d54b3..e535dc18a1f 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -5301,6 +5301,8 @@ class VIEW3D_MT_pivot_pie(Menu):
pie.prop_enum(context.scene.tool_settings, "transform_pivot_point", value='ACTIVE_ELEMENT')
if (obj is None) or (mode in {'OBJECT', 'POSE', 'WEIGHT_PAINT'}):
pie.prop(context.scene.tool_settings, "use_transform_pivot_point_align")
+ if mode in {'EDIT_GPENCIL'}:
+ pie.prop(context.scene.tool_settings.gpencil_sculpt, "use_scale_thickness")
class VIEW3D_MT_orientations_pie(Menu):
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt
index dee163a9797..deff45d0350 100644
--- a/source/blender/CMakeLists.txt
+++ b/source/blender/CMakeLists.txt
@@ -19,6 +19,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_constraint_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curve_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curveprofile_types.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_curves_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_customdata_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_defs.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_documentation.h
@@ -31,7 +32,6 @@ 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_curves_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
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 3817fe59f95..058b0f120f7 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -44,7 +44,7 @@ int BLF_load_mem_unique(const char *name, const unsigned char *mem, int mem_size
void BLF_unload(const char *name) ATTR_NONNULL();
void BLF_unload_id(int fontid);
-char *BLF_display_name_from_file(const char *filename);
+char *BLF_display_name_from_file(const char *filepath);
/**
* Check if font supports a particular glyph.
@@ -279,7 +279,7 @@ void BLF_dir_free(char **dirs, int count) ATTR_NONNULL();
*
* \note called from a thread, so it bypasses the normal BLF_* api (which isn't thread-safe).
*/
-void BLF_thumb_preview(const char *filename,
+void BLF_thumb_preview(const char *filepath,
const char **draw_str,
const char **i18n_draw_str,
unsigned char draw_str_lines,
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 043d6da7d73..2b5a2cdf606 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -129,7 +129,7 @@ bool BLF_has_glyph(int fontid, unsigned int unicode)
{
FontBLF *font = blf_get(fontid);
if (font) {
- return FT_Get_Char_Index(font->face, unicode) != 0;
+ return FT_Get_Char_Index(font->face, unicode) != FT_Err_Ok;
}
return false;
}
@@ -158,14 +158,14 @@ int BLF_load_unique(const char *name)
return -1;
}
- char *filename = blf_dir_search(name);
- if (!filename) {
+ char *filepath = blf_dir_search(name);
+ if (!filepath) {
printf("Can't find font: %s\n", name);
return -1;
}
- FontBLF *font = blf_font_new(name, filename);
- MEM_freeN(filename);
+ FontBLF *font = blf_font_new(name, filepath);
+ MEM_freeN(filepath);
if (!font) {
printf("Can't load font: %s\n", name);
@@ -869,9 +869,9 @@ void BLF_draw_buffer(int fontid, const char *str, const size_t str_len)
BLF_draw_buffer_ex(fontid, str, str_len, NULL);
}
-char *BLF_display_name_from_file(const char *filename)
+char *BLF_display_name_from_file(const char *filepath)
{
- FontBLF *font = blf_font_new("font_name", filename);
+ FontBLF *font = blf_font_new("font_name", filepath);
if (!font) {
return NULL;
}
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index 69b44ed9b01..8534a8c583f 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -132,12 +132,12 @@ char *blf_dir_search(const char *file)
return s;
}
-char *blf_dir_metrics_search(const char *filename)
+char *blf_dir_metrics_search(const char *filepath)
{
char *mfile;
char *s;
- mfile = BLI_strdup(filename);
+ mfile = BLI_strdup(filepath);
s = strrchr(mfile, '.');
if (s) {
if (BLI_strnlen(s, 4) < 4) {
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index c4bd22d1310..60ff5f6470f 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -1213,14 +1213,14 @@ static void blf_font_fill(FontBLF *font)
font->glyph_cache_mutex = &blf_glyph_cache_mutex;
}
-FontBLF *blf_font_new(const char *name, const char *filename)
+FontBLF *blf_font_new(const char *name, const char *filepath)
{
FontBLF *font;
FT_Error err;
char *mfile;
font = (FontBLF *)MEM_callocN(sizeof(FontBLF), "blf_font_new");
- err = FT_New_Face(ft_lib, filename, 0, &font->face);
+ err = FT_New_Face(ft_lib, filepath, 0, &font->face);
if (err) {
if (ELEM(err, FT_Err_Unknown_File_Format, FT_Err_Unimplemented_Feature)) {
printf("Format of this font file is not supported\n");
@@ -1246,17 +1246,17 @@ FontBLF *blf_font_new(const char *name, const char *filename)
return NULL;
}
- mfile = blf_dir_metrics_search(filename);
+ mfile = blf_dir_metrics_search(filepath);
if (mfile) {
err = FT_Attach_File(font->face, mfile);
if (err) {
- fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filename, (int)err);
+ fprintf(stderr, "FT_Attach_File failed to load '%s' with error %d\n", filepath, (int)err);
}
MEM_freeN(mfile);
}
font->name = BLI_strdup(name);
- font->filename = BLI_strdup(filename);
+ font->filepath = BLI_strdup(filepath);
blf_font_fill(font);
if (FT_HAS_KERNING(font->face)) {
@@ -1303,7 +1303,7 @@ FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int m
}
font->name = BLI_strdup(name);
- font->filename = NULL;
+ font->filepath = NULL;
blf_font_fill(font);
return font;
}
@@ -1317,8 +1317,8 @@ void blf_font_free(FontBLF *font)
}
FT_Done_Face(font->face);
- if (font->filename) {
- MEM_freeN(font->filename);
+ if (font->filepath) {
+ MEM_freeN(font->filepath);
}
if (font->name) {
MEM_freeN(font->name);
@@ -1340,7 +1340,7 @@ bool blf_font_size(FontBLF *font, float size, unsigned int dpi)
size = (float)ft_size / 64.0f;
if (font->size != size || font->dpi != dpi) {
- if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == 0) {
+ if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) == FT_Err_Ok) {
font->size = size;
font->dpi = dpi;
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index 4810e46b1d2..28531c5afc1 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -258,7 +258,7 @@ static FT_GlyphSlot blf_glyph_load(FontBLF *font, FT_UInt glyph_index)
}
}
- if (FT_Load_Glyph(font->face, glyph_index, load_flags) == 0) {
+ if (FT_Load_Glyph(font->face, glyph_index, load_flags) == FT_Err_Ok) {
return font->face->glyph;
}
return NULL;
@@ -280,7 +280,7 @@ static bool blf_glyph_render_bitmap(FontBLF *font, FT_GlyphSlot glyph)
/* Render the glyph curves to a bitmap. */
FT_Error err = FT_Render_Glyph(glyph, render_mode);
- if (err != 0) {
+ if (err != FT_Err_Ok) {
return false;
}
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 14e1a8f72d1..81a1460df4d 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -25,7 +25,7 @@ char *blf_dir_search(const char *file);
* Some font have additional file with metrics information,
* in general, the extension of the file is: `.afm` or `.pfm`
*/
-char *blf_dir_metrics_search(const char *filename);
+char *blf_dir_metrics_search(const char *filepath);
/* int blf_dir_split(const char *str, char *file, int *size); */ /* UNUSED */
int blf_font_init(void);
@@ -36,7 +36,7 @@ bool blf_font_id_is_valid(int fontid);
void blf_draw_buffer__start(struct FontBLF *font);
void blf_draw_buffer__end(void);
-struct FontBLF *blf_font_new(const char *name, const char *filename);
+struct FontBLF *blf_font_new(const char *name, const char *filepath);
struct FontBLF *blf_font_new_from_mem(const char *name, const unsigned char *mem, int mem_size);
void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, int mem_size);
diff --git a/source/blender/blenfont/intern/blf_internal_types.h b/source/blender/blenfont/intern/blf_internal_types.h
index 61b6edc4974..23dc2fda38c 100644
--- a/source/blender/blenfont/intern/blf_internal_types.h
+++ b/source/blender/blenfont/intern/blf_internal_types.h
@@ -147,8 +147,8 @@ typedef struct FontBLF {
/* # of times this font was loaded */
unsigned int reference_count;
- /* filename or NULL. */
- char *filename;
+ /** File-path or NULL. */
+ char *filepath;
/* aspect ratio or scale. */
float aspect[3];
diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c
index 9d9a8a51d0f..0e265fb7553 100644
--- a/source/blender/blenfont/intern/blf_thumbs.c
+++ b/source/blender/blenfont/intern/blf_thumbs.c
@@ -29,7 +29,7 @@
#include "BLI_strict_flags.h"
-void BLF_thumb_preview(const char *filename,
+void BLF_thumb_preview(const char *filepath,
const char **draw_str,
const char **i18n_draw_str,
const unsigned char draw_str_lines,
@@ -49,9 +49,9 @@ void BLF_thumb_preview(const char *filename,
FontBLF *font;
/* Create a new blender font obj and fill it with default values */
- font = blf_font_new("thumb_font", filename);
+ font = blf_font_new("thumb_font", filepath);
if (!font) {
- printf("Info: Can't load font '%s', no preview possible\n", filename);
+ printf("Info: Can't load font '%s', no preview possible\n", filepath);
return;
}
@@ -73,7 +73,7 @@ void BLF_thumb_preview(const char *filename,
for (int i = 0; i < draw_str_lines; i++) {
const char *draw_str_i18n = i18n_draw_str[i] != NULL ? i18n_draw_str[i] : draw_str[i];
const size_t draw_str_i18n_len = strlen(draw_str_i18n);
- int draw_str_i18n_nbr = 0;
+ int draw_str_i18_count = 0;
CLAMP_MIN(font_size_curr, font_size_min);
if (!blf_font_size(font, (float)font_size_curr, dpi)) {
@@ -91,8 +91,8 @@ void BLF_thumb_preview(const char *filename,
* since many fonts will then show nothing but ugly 'missing char' in their preview).
* Does not handle all cases, but much better than nothing.
*/
- if (blf_font_count_missing_chars(font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18n_nbr) >
- (draw_str_i18n_nbr / 2)) {
+ if (blf_font_count_missing_chars(font, draw_str_i18n, draw_str_i18n_len, &draw_str_i18_count) >
+ (draw_str_i18_count / 2)) {
blf_font_draw_buffer(font, draw_str[i], strlen(draw_str[i]), NULL);
}
else {
diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh
index 3075c0689e9..9efa64d1474 100644
--- a/source/blender/blenkernel/BKE_attribute_math.hh
+++ b/source/blender/blenkernel/BKE_attribute_math.hh
@@ -22,7 +22,7 @@ inline void convert_to_static_type(const CPPType &cpp_type, const Func &func)
[&](auto type_tag) {
using T = typename decltype(type_tag)::type;
if constexpr (std::is_same_v<T, void>) {
- /* It's expected that the given cpp type is one of the supported once. */
+ /* It's expected that the given cpp type is one of the supported ones. */
BLI_assert_unreachable();
}
else {
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index eb4f8f5d5c8..82f77d83bec 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -122,14 +122,14 @@ class CurvesGeometry : public ::CurvesGeometry {
* Accessors.
*/
- int points_size() const;
- int curves_size() const;
+ int points_num() const;
+ int curves_num() const;
IndexRange points_range() const;
IndexRange curves_range() const;
/**
* The index of the first point in every curve. The size of this span is one larger than the
- * number of curves. Consider using #range_for_curve rather than using the offsets directly.
+ * number of curves. Consider using #points_for_curve rather than using the offsets directly.
*/
Span<int> offsets() const;
MutableSpan<int> offsets();
@@ -137,8 +137,8 @@ class CurvesGeometry : public ::CurvesGeometry {
/**
* Access a range of indices of point data for a specific curve.
*/
- IndexRange range_for_curve(int index) const;
- IndexRange range_for_curves(IndexRange curves) const;
+ IndexRange points_for_curve(int index) const;
+ IndexRange points_for_curves(IndexRange curves) const;
/** The type (#CurveType) of each curve, or potentially a single if all are the same type. */
VArray<int8_t> curve_types() const;
@@ -146,6 +146,8 @@ class CurvesGeometry : public ::CurvesGeometry {
MutableSpan<int8_t> curve_types();
bool has_curve_with_type(const CurveType type) const;
+ /** Return the number of curves with each type. */
+ std::array<int, CURVE_TYPES_NUM> count_curve_types() const;
MutableSpan<float3> positions();
Span<float3> positions() const;
@@ -243,23 +245,36 @@ class CurvesGeometry : public ::CurvesGeometry {
* The total number of points in the evaluated poly curve.
* This can depend on the resolution attribute if it exists.
*/
- int evaluated_points_size() const;
+ int evaluated_points_num() const;
/**
* Access a range of indices of point data for a specific curve.
* Call #evaluated_offsets() first to ensure that the evaluated offsets cache is current.
*/
- IndexRange evaluated_range_for_curve(int index) const;
+ IndexRange evaluated_points_for_curve(int index) const;
+ IndexRange evaluated_points_for_curves(IndexRange curves) const;
/**
* The index of the first evaluated point for every curve. The size of this span is one larger
- * than the number of curves. Consider using #evaluated_range_for_curve rather than using the
+ * than the number of curves. Consider using #evaluated_points_for_curve rather than using the
* offsets directly.
*/
Span<int> evaluated_offsets() const;
+ /** Makes sure the data described by #evaluated_offsets if necessary. */
+ void ensure_evaluated_offsets() const;
+
Span<float3> evaluated_positions() const;
+ /**
+ * Evaluate a generic data to the standard evaluated points of a specific curve,
+ * defined by the resolution attribute or other factors, depending on the curve type.
+ *
+ * \warning This function expects offsets to the evaluated points for each curve to be
+ * calculated. That can be ensured with #ensure_evaluated_offsets.
+ */
+ void interpolate_to_evaluated(int curve_index, GSpan src, GMutableSpan dst) const;
+
private:
/**
* Make sure the basis weights for NURBS curve's evaluated points are calculated.
@@ -275,7 +290,7 @@ class CurvesGeometry : public ::CurvesGeometry {
* Change the number of elements. New values for existing attributes should be properly
* initialized afterwards.
*/
- void resize(int point_size, int curve_size);
+ void resize(int points_num, int curves_num);
/** Call after deforming the position attribute. */
void tag_positions_changed();
@@ -314,9 +329,9 @@ namespace curves {
* and the fact that curves with two points cannot be cyclic. The logic is simple, but this
* function should be used to make intentions clearer.
*/
-inline int curve_segment_size(const int size, const bool cyclic)
+inline int curve_segment_size(const int points_num, const bool cyclic)
{
- return (cyclic && size > 2) ? size : size - 1;
+ return (cyclic && points_num > 2) ? points_num : points_num - 1;
}
namespace bezier {
@@ -375,16 +390,23 @@ void calculate_evaluated_positions(Span<float3> positions,
Span<int> evaluated_offsets,
MutableSpan<float3> evaluated_positions);
+/**
+ * Evaluate generic data to the evaluated points, with counts for each segment described by
+ * #evaluated_offsets. Unlike other curve types, for Bezier curves generic data and positions
+ * are treated separately, since attribute values aren't stored for the handle control points.
+ */
+void interpolate_to_evaluated(GSpan src, Span<int> evaluated_offsets, GMutableSpan dst);
+
} // namespace bezier
namespace catmull_rom {
/**
* Calculate the number of evaluated points that #interpolate_to_evaluated is expected to produce.
- * \param size: The number of points in the curve.
+ * \param points_num: The number of points in the curve.
* \param resolution: The resolution for each segment.
*/
-int calculate_evaluated_size(int size, bool cyclic, int resolution);
+int calculate_evaluated_size(int points_num, bool cyclic, int resolution);
/**
* Evaluate the Catmull Rom curve. The length of the #dst span should be calculated with
@@ -399,7 +421,7 @@ namespace nurbs {
/**
* Checks the conditions that a NURBS curve needs to evaluate.
*/
-bool check_valid_size_and_order(int size, int8_t order, bool cyclic, KnotsMode knots_mode);
+bool check_valid_size_and_order(int points_num, int8_t order, bool cyclic, KnotsMode knots_mode);
/**
* Calculate the standard evaluated size for a NURBS curve, using the standard that
@@ -410,14 +432,14 @@ bool check_valid_size_and_order(int size, int8_t order, bool cyclic, KnotsMode k
* shared.
*/
int calculate_evaluated_size(
- int size, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode);
+ int points_num, int8_t order, bool cyclic, int resolution, KnotsMode knots_mode);
/**
* Calculate the length of the knot vector for a NURBS curve with the given properties.
* The knots must be longer for a cyclic curve, for example, in order to provide weights for the
* last evaluated points that are also influenced by the first control points.
*/
-int knots_size(int size, int8_t order, bool cyclic);
+int knots_size(int points_num, int8_t order, bool cyclic);
/**
* Calculate the knots for a spline given its properties, based on built-in standards defined by
@@ -428,7 +450,7 @@ int knots_size(int size, int8_t order, bool cyclic);
* changes, and is generally more intuitive than defining the knot vector manually.
*/
void calculate_knots(
- int size, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots);
+ int points_num, KnotsMode mode, int8_t order, bool cyclic, MutableSpan<float> knots);
/**
* Based on the knots, the order, and other properties of a NURBS curve, calculate a cache that can
@@ -436,7 +458,7 @@ void calculate_knots(
* two pieces of information for every evaluated point: the first control point that influences it,
* and a weight for each control point.
*/
-void calculate_basis_cache(int size,
+void calculate_basis_cache(int points_num,
int evaluated_size,
int8_t order,
bool cyclic,
@@ -461,11 +483,11 @@ void interpolate_to_evaluated(const BasisCache &basis_cache,
} // namespace curves
-Curves *curves_new_nomain(int point_size, int curves_size);
+Curves *curves_new_nomain(int points_num, int curves_num);
/**
* Create a new curves data-block containing a single curve with the given length and type.
*/
-Curves *curves_new_nomain_single(int point_size, CurveType type);
+Curves *curves_new_nomain_single(int points_num, CurveType type);
} // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 911f4aab394..6b805a4c29d 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -589,7 +589,7 @@ void CustomData_layers__print(struct CustomData *data);
/* External file storage */
void CustomData_external_add(
- struct CustomData *data, struct ID *id, int type, int totelem, const char *filename);
+ struct CustomData *data, struct ID *id, int type, int totelem, const char *filepath);
void CustomData_external_remove(struct CustomData *data, struct ID *id, int type, int totelem);
bool CustomData_external_test(struct CustomData *data, int type);
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 5a1c99774fd..109d3e6d977 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -129,7 +129,7 @@ int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface,
struct Object *cObject,
int frame);
void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface,
- char *filename,
+ const char *filepath,
short output_layer);
/* PaintPoint state */
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 4127030e96f..ad3b1971ca9 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -220,30 +220,78 @@ bool BKE_gpencil_stroke_sample(struct bGPdata *gpd,
* \param gps: Stroke to smooth
* \param i: Point index
* \param inf: Amount of smoothing to apply
+ * \param iterations: Radius of points to consider, equivalent to iterations
* \param smooth_caps: Apply smooth to stroke extremes
+ * \param keep_shape: Smooth out fine details first
+ * \param r_gps: Stroke to put the result into
*/
-bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, int i, float inf, bool smooth_caps);
+bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps,
+ int point_index,
+ float influence,
+ int iterations,
+ bool smooth_caps,
+ bool keep_shape,
+ struct bGPDstroke *r_gps);
/**
* Apply smooth strength to stroke point.
* \param gps: Stroke to smooth
* \param point_index: Point index
* \param influence: Amount of smoothing to apply
+ * \param iterations: Radius of points to consider, equivalent to iterations
+ * \param r_gps: Stroke to put the result into
*/
-bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, int point_index, float influence);
+bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps,
+ int point_index,
+ float influence,
+ int iterations,
+ struct bGPDstroke *r_gps);
/**
* Apply smooth for thickness to stroke point (use pressure).
* \param gps: Stroke to smooth
* \param point_index: Point index
* \param influence: Amount of smoothing to apply
+ * \param iterations: Radius of points to consider, equivalent to iterations
+ * \param r_gps: Stroke to put the result into
*/
-bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps, int point_index, float influence);
+bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps,
+ int point_index,
+ float influence,
+ int iterations,
+ struct bGPDstroke *r_gps);
/**
- * Apply smooth for UV rotation to stroke point (use pressure).
+ * Apply smooth for UV rotation/factor to stroke point.
* \param gps: Stroke to smooth
* \param point_index: Point index
* \param influence: Amount of smoothing to apply
+ * \param iterations: Radius of points to consider, equivalent to iterations
+ * \param r_gps: Stroke to put the result into
*/
-bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps, int point_index, float influence);
+bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps,
+ int point_index,
+ float influence,
+ int iterations,
+ struct bGPDstroke *r_gps);
+/**
+ * Apply smooth operation to the stroke.
+ * \param gps: Stroke to smooth
+ * \param influence: The interpolation factor for the smooth and the original stroke
+ * \param iterations: Radius of points to consider, equivalent to iterations
+ * \param smooth_position: Smooth point locations
+ * \param smooth_strength: Smooth point strength
+ * \param smooth_thickness: Smooth point thickness
+ * \param smooth_uv: Smooth uv rotation/factor
+ * \param keep_shape: Use different distribution for smooth locations to keep the shape
+ * \param weights: per point weights to multiply influence with (optional, can be null)
+ */
+void BKE_gpencil_stroke_smooth(struct bGPDstroke *gps,
+ const float influence,
+ const int iterations,
+ const bool smooth_position,
+ const bool smooth_strength,
+ const bool smooth_thickness,
+ const bool smooth_uv,
+ const bool keep_shape,
+ const float *weights);
/**
* Close grease pencil stroke.
* \param gps: Stroke to close
diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh
index 8cbb8819551..393bf003caa 100644
--- a/source/blender/blenkernel/BKE_image_partial_update.hh
+++ b/source/blender/blenkernel/BKE_image_partial_update.hh
@@ -165,6 +165,7 @@ class ImageTileData : AbstractTileData {
* Can be nullptr when the file doesn't exist or when the tile hasn't been initialized.
*/
ImBuf *tile_buffer = nullptr;
+ void *tile_buffer_lock = nullptr;
ImageTileData(Image *image, ImageUser *image_user) : image(image)
{
@@ -177,14 +178,15 @@ class ImageTileData : AbstractTileData {
{
image_user.tile = new_tile_number;
tile = BKE_image_get_tile(image, new_tile_number);
- tile_buffer = BKE_image_acquire_ibuf(image, &image_user, NULL);
+ tile_buffer = BKE_image_acquire_ibuf(image, &image_user, &tile_buffer_lock);
}
void free_data() override
{
- BKE_image_release_ibuf(image, tile_buffer, nullptr);
+ BKE_image_release_ibuf(image, tile_buffer, tile_buffer_lock);
tile = nullptr;
tile_buffer = nullptr;
+ tile_buffer_lock = nullptr;
}
};
diff --git a/source/blender/blenkernel/BKE_image_save.h b/source/blender/blenkernel/BKE_image_save.h
index b022e677845..052fc937af9 100644
--- a/source/blender/blenkernel/BKE_image_save.h
+++ b/source/blender/blenkernel/BKE_image_save.h
@@ -49,21 +49,26 @@ bool BKE_image_save(struct ReportList *reports,
/* Render saving. */
-/* Save single or multilayer OpenEXR files from the render result.
- * Optionally saves only a specific view or layer. */
+/**
+ * Save single or multi-layer OpenEXR files from the render result.
+ * Optionally saves only a specific view or layer.
+ */
bool BKE_image_render_write_exr(struct ReportList *reports,
const struct RenderResult *rr,
- const char *filename,
+ const char *filepath,
const struct ImageFormatData *imf,
const bool save_as_render,
const char *view,
int layer);
+/**
+ * \param filepath_basis: May be used as-is, or used as a basis for multi-view images.
+ */
bool BKE_image_render_write(struct ReportList *reports,
struct RenderResult *rr,
const struct Scene *scene,
const bool stamp,
- const char *name);
+ const char *filepath_basis);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 7f099125706..77a3223c064 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -301,10 +301,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_SELECTED_OBJECT_BEGIN(_view_layer, _v3d, _instance) \
{ \
- struct ObjectsVisibleIteratorData data_ = { \
- .view_layer = _view_layer, \
- .v3d = _v3d, \
- }; \
+ struct ObjectsVisibleIteratorData data_ = {NULL}; \
+ data_.view_layer = _view_layer; \
+ data_.v3d = _v3d; \
ITER_BEGIN (BKE_view_layer_selected_objects_iterator_begin, \
BKE_view_layer_selected_objects_iterator_next, \
BKE_view_layer_selected_objects_iterator_end, \
@@ -319,7 +318,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_SELECTED_EDITABLE_OBJECT_BEGIN(_view_layer, _v3d, _instance) \
{ \
- struct ObjectsVisibleIteratorData data_ = {_view_layer, _v3d}; \
+ struct ObjectsVisibleIteratorData data_ = {NULL}; \
+ data_.view_layer = _view_layer; \
+ data_.v3d = _v3d; \
ITER_BEGIN (BKE_view_layer_selected_editable_objects_iterator_begin, \
BKE_view_layer_selected_editable_objects_iterator_next, \
BKE_view_layer_selected_editable_objects_iterator_end, \
@@ -334,10 +335,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_VISIBLE_OBJECT_BEGIN(_view_layer, _v3d, _instance) \
{ \
- struct ObjectsVisibleIteratorData data_ = { \
- .view_layer = _view_layer, \
- .v3d = _v3d, \
- }; \
+ struct ObjectsVisibleIteratorData data_ = {NULL}; \
+ data_.view_layer = _view_layer; \
+ data_.v3d = _v3d; \
ITER_BEGIN (BKE_view_layer_visible_objects_iterator_begin, \
BKE_view_layer_visible_objects_iterator_next, \
BKE_view_layer_visible_objects_iterator_end, \
@@ -404,10 +404,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
#define FOREACH_VISIBLE_BASE_BEGIN(_view_layer, _v3d, _instance) \
{ \
- struct ObjectsVisibleIteratorData data_ = { \
- .view_layer = _view_layer, \
- .v3d = _v3d, \
- }; \
+ struct ObjectsVisibleIteratorData data_ = {NULL}; \
+ data_.view_layer = _view_layer; \
+ data_.v3d = _v3d; \
ITER_BEGIN (BKE_view_layer_visible_bases_iterator_begin, \
BKE_view_layer_visible_bases_iterator_next, \
BKE_view_layer_visible_bases_iterator_end, \
@@ -437,10 +436,9 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter);
IteratorBeginCb func_begin; \
IteratorCb func_next, func_end; \
void *data_in; \
- struct ObjectsVisibleIteratorData data_ = { \
- .view_layer = _view_layer, \
- .v3d = _v3d, \
- }; \
+ struct ObjectsVisibleIteratorData data_ = {NULL}; \
+ data_.view_layer = _view_layer; \
+ data_.v3d = _v3d; \
\
if (flag == SELECT) { \
func_begin = &BKE_view_layer_selected_objects_iterator_begin; \
diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h
index 040be8d1280..c3122758a72 100644
--- a/source/blender/blenkernel/BKE_lib_id.h
+++ b/source/blender/blenkernel/BKE_lib_id.h
@@ -515,7 +515,7 @@ void BKE_main_id_flag_listbase(struct ListBase *lb, int flag, bool value);
void BKE_main_id_flag_all(struct Main *bmain, int flag, bool value);
/**
- * Next to indirect usage in `readfile.c/writefile.c` also in `editobject.c`, `scene.c`.
+ * Next to indirect usage in `readfile.c/writefile.c` also in `editobject.c`, `scene.cc`.
*/
void BKE_main_id_newptr_and_tag_clear(struct Main *bmain);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 0ba9713b96d..1ad20c52a4b 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -571,7 +571,7 @@ typedef struct MLoopNorSpaceArray {
struct LinkNode
*loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */
char data_type; /* Whether we store loop indices, or pointers to BMLoop. */
- int num_spaces; /* Number of clnors spaces defined in this array. */
+ int spaces_num; /* Number of clnors spaces defined in this array. */
struct MemArena *mem;
} MLoopNorSpaceArray;
/**
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index 8433894b8c5..893aa2a5b1c 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -45,7 +45,7 @@ enum ePF_FileStatus {
struct PackedFile *BKE_packedfile_duplicate(const struct PackedFile *pf_src);
struct PackedFile *BKE_packedfile_new(struct ReportList *reports,
- const char *filename,
+ const char *filepath,
const char *basepath);
struct PackedFile *BKE_packedfile_new_from_memory(void *mem, int memlen);
@@ -102,7 +102,7 @@ int BKE_packedfile_unpack_all_libraries(struct Main *bmain, struct ReportList *r
int BKE_packedfile_write_to_file(struct ReportList *reports,
const char *ref_file_name,
- const char *filename,
+ const char *filepath,
struct PackedFile *pf,
bool guimode);
@@ -122,7 +122,7 @@ int BKE_packedfile_count_all(struct Main *bmain);
* - #PF_NOFILE: the original file doesn't exist.
*/
enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name,
- const char *filename,
+ const char *filepath_rel,
struct PackedFile *pf);
/* Read. */
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 8c50a89ec90..a6402a1e8a1 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -225,7 +225,7 @@ bool BKE_scene_remove_render_view(struct Scene *scene, struct SceneRenderView *s
/* Render profile. */
int get_render_subsurf_level(const struct RenderData *r, int lvl, bool for_render);
-int get_render_child_particle_number(const struct RenderData *r, int num, bool for_render);
+int get_render_child_particle_number(const struct RenderData *r, int child_num, bool for_render);
bool BKE_scene_use_shading_nodes_custom(struct Scene *scene);
bool BKE_scene_use_spherical_stereo(struct Scene *scene);
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index e4edd01481b..a39d981d74f 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -104,8 +104,6 @@ set(SRC
intern/crazyspace.c
intern/cryptomatte.cc
intern/curve.cc
- intern/curves.cc
- intern/curves_geometry.cc
intern/curve_bevel.c
intern/curve_bezier.cc
intern/curve_catmull_rom.cc
@@ -116,6 +114,8 @@ set(SRC
intern/curve_nurbs.cc
intern/curve_to_mesh_convert.cc
intern/curveprofile.cc
+ intern/curves.cc
+ intern/curves_geometry.cc
intern/customdata.cc
intern/customdata_file.c
intern/data_transfer.c
@@ -157,9 +157,9 @@ set(SRC
intern/idtype.c
intern/image.cc
intern/image_format.cc
- intern/image_partial_update.cc
intern/image_gen.c
intern/image_gpu.cc
+ intern/image_partial_update.cc
intern/image_save.cc
intern/ipo.c
intern/kelvinlet.c
@@ -248,7 +248,7 @@ set(SRC
intern/preferences.c
intern/report.c
intern/rigidbody.c
- intern/scene.c
+ intern/scene.cc
intern/screen.c
intern/shader_fx.c
intern/shrinkwrap.c
@@ -349,10 +349,10 @@ set(SRC
BKE_cryptomatte.h
BKE_cryptomatte.hh
BKE_curve.h
- BKE_curves.h
- BKE_curves.hh
BKE_curve_to_mesh.hh
BKE_curveprofile.h
+ BKE_curves.h
+ BKE_curves.hh
BKE_customdata.h
BKE_customdata_file.h
BKE_data_transfer.h
@@ -600,14 +600,14 @@ if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON)
endif()
-if(WITH_IMAGE_FRAMESERVER)
- add_definitions(-DWITH_FRAMESERVER)
-endif()
-
if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
+
if(WITH_CODEC_AVI)
list(APPEND INC
../io/avi
@@ -821,6 +821,7 @@ if(WITH_GTESTS)
intern/fcurve_test.cc
intern/idprop_serialize_test.cc
intern/image_partial_update_test.cc
+ intern/image_test.cc
intern/lattice_deform_test.cc
intern/layer_test.cc
intern/lib_id_remapper_test.cc
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index b0393ed723d..8d3649fef08 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -1022,16 +1022,16 @@ void BKE_appdir_app_templates(ListBase *templates)
continue;
}
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(subdir, &dir);
- for (int f = 0; f < totfile; f++) {
- if (!FILENAME_IS_CURRPAR(dir[f].relname) && S_ISDIR(dir[f].type)) {
- char *template = BLI_strdup(dir[f].relname);
+ struct direntry *dirs;
+ const uint dir_num = BLI_filelist_dir_contents(subdir, &dirs);
+ for (int f = 0; f < dir_num; f++) {
+ if (!FILENAME_IS_CURRPAR(dirs[f].relname) && S_ISDIR(dirs[f].type)) {
+ char *template = BLI_strdup(dirs[f].relname);
BLI_addtail(templates, BLI_genericNodeN(template));
}
}
- BLI_filelist_free(dir, totfile);
+ BLI_filelist_free(dirs, dir_num);
}
}
diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c
index 294fe57c923..be2abdbfb69 100644
--- a/source/blender/blenkernel/intern/blendfile_link_append.c
+++ b/source/blender/blenkernel/intern/blendfile_link_append.c
@@ -999,7 +999,7 @@ static void blendfile_link_append_proxies_convert(Main *bmain, ReportList *repor
RPT_WARNING,
"Proxies have been removed from Blender (%d proxies were automatically converted "
"to library overrides, %d proxies could not be converted and were cleared). "
- "Please consider re-saving any library .blend file with the newest Blender version.",
+ "Please consider re-saving any library .blend file with the newest Blender version",
bf_reports.count.proxies_to_lib_overrides_success,
bf_reports.count.proxies_to_lib_overrides_failures);
}
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 891145b47c9..bdaea487cfb 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -432,7 +432,8 @@ void BKE_collection_add_from_object(Main *bmain,
bool is_instantiated = false;
FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
- if (!ID_IS_LINKED(collection) && BKE_collection_has_object(collection, ob_src)) {
+ if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDABLE_LIBRARY(collection) &&
+ BKE_collection_has_object(collection, ob_src)) {
collection_child_add(collection, collection_dst, 0, true);
is_instantiated = true;
}
@@ -454,7 +455,8 @@ void BKE_collection_add_from_collection(Main *bmain,
bool is_instantiated = false;
FOREACH_SCENE_COLLECTION_BEGIN (scene, collection) {
- if (!ID_IS_LINKED(collection) && collection_find_child(collection, collection_src)) {
+ if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDABLE_LIBRARY(collection) &&
+ collection_find_child(collection, collection_src)) {
collection_child_add(collection, collection_dst, 0, true);
is_instantiated = true;
}
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 9d13bf3ac11..96389c44839 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -236,7 +236,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
ModifierData *md;
Mesh *me_input = ob->data;
Mesh *me = NULL;
- int i, a, numleft = 0, numVerts = 0;
+ int i, a, modifiers_left_num = 0, verts_num = 0;
int cageIndex = BKE_modifiers_get_cage_index(scene, ob, NULL, 1);
float(*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
VirtualModifierData virtualModifierData;
@@ -266,14 +266,14 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
BLI_linklist_free((LinkNode *)datamasks, NULL);
me = BKE_mesh_wrapper_from_editmesh_with_coords(em, &cd_mask_extra, NULL, me_input);
- deformedVerts = editbmesh_vert_coords_alloc(em, &numVerts);
- defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats");
+ deformedVerts = editbmesh_vert_coords_alloc(em, &verts_num);
+ defmats = MEM_mallocN(sizeof(*defmats) * verts_num, "defmats");
- for (a = 0; a < numVerts; a++) {
+ for (a = 0; a < verts_num; a++) {
unit_m3(defmats[a]);
}
}
- mti->deformMatricesEM(md, &mectx, em, me, deformedVerts, defmats, numVerts);
+ mti->deformMatricesEM(md, &mectx, em, me, deformedVerts, defmats, verts_num);
}
else {
break;
@@ -283,7 +283,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
for (; md && i <= cageIndex; md = md->next, i++) {
if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) &&
BKE_modifier_is_correctable_deformed(md)) {
- numleft++;
+ modifiers_left_num++;
}
}
@@ -294,7 +294,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra
*deformmats = defmats;
*deformcos = deformedVerts;
- return numleft;
+ return modifiers_left_num;
}
/**
@@ -319,13 +319,13 @@ static void crazyspace_init_verts_and_matrices(const Mesh *mesh,
float (**deformmats)[3][3],
float (**deformcos)[3])
{
- int num_verts;
- *deformcos = BKE_mesh_vert_coords_alloc(mesh, &num_verts);
- *deformmats = MEM_callocN(sizeof(**deformmats) * num_verts, "defmats");
- for (int a = 0; a < num_verts; a++) {
+ int verts_num;
+ *deformcos = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
+ *deformmats = MEM_callocN(sizeof(**deformmats) * verts_num, "defmats");
+ for (int a = 0; a < verts_num; a++) {
unit_m3((*deformmats)[a]);
}
- BLI_assert(num_verts == mesh->totvert);
+ BLI_assert(verts_num == mesh->totvert);
}
static bool crazyspace_modifier_supports_deform_matrices(ModifierData *md)
@@ -352,7 +352,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
ModifierData *md;
Mesh *me_eval = NULL;
float(*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
- int numleft = 0;
+ int modifiers_left_num = 0;
VirtualModifierData virtualModifierData;
Object object_eval;
crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
@@ -364,7 +364,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
if (is_sculpt_mode && has_multires) {
*deformmats = NULL;
*deformcos = NULL;
- return numleft;
+ return modifiers_left_num;
}
md = BKE_modifiers_get_virtual_modifierlist(&object_eval, &virtualModifierData);
@@ -401,7 +401,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
}
if (crazyspace_modifier_supports_deform(md)) {
- numleft++;
+ modifiers_left_num++;
}
}
@@ -412,7 +412,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
*deformmats = defmats;
*deformcos = deformedVerts;
- return numleft;
+ return modifiers_left_num;
}
void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph,
@@ -489,13 +489,13 @@ void BKE_crazyspace_build_sculpt(struct Depsgraph *depsgraph,
}
if (*deformmats == NULL) {
- int a, numVerts;
+ int a, verts_num;
Mesh *mesh = (Mesh *)object->data;
- *deformcos = BKE_mesh_vert_coords_alloc(mesh, &numVerts);
- *deformmats = MEM_callocN(sizeof(*(*deformmats)) * numVerts, "defmats");
+ *deformcos = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
+ *deformmats = MEM_callocN(sizeof(*(*deformmats)) * verts_num, "defmats");
- for (a = 0; a < numVerts; a++) {
+ for (a = 0; a < verts_num; a++) {
unit_m3((*deformmats)[a]);
}
}
@@ -523,7 +523,7 @@ void BKE_crazyspace_api_eval(Depsgraph *depsgraph,
}
const Mesh *mesh = (const Mesh *)object->data;
- object->runtime.crazyspace_num_verts = mesh->totvert;
+ object->runtime.crazyspace_verts_num = mesh->totvert;
BKE_crazyspace_build_sculpt(depsgraph,
scene,
object,
@@ -537,12 +537,12 @@ void BKE_crazyspace_api_displacement_to_deformed(struct Object *object,
float displacement[3],
float r_displacement_deformed[3])
{
- if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) {
+ if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_verts_num) {
BKE_reportf(reports,
RPT_ERROR,
"Invalid vertex index %d (expected to be within 0 to %d range)",
vertex_index,
- object->runtime.crazyspace_num_verts);
+ object->runtime.crazyspace_verts_num);
return;
}
@@ -557,12 +557,12 @@ void BKE_crazyspace_api_displacement_to_original(struct Object *object,
float displacement_deformed[3],
float r_displacement[3])
{
- if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_num_verts) {
+ if (vertex_index < 0 || vertex_index >= object->runtime.crazyspace_verts_num) {
BKE_reportf(reports,
RPT_ERROR,
"Invalid vertex index %d (expected to be within 0 to %d range))",
vertex_index,
- object->runtime.crazyspace_num_verts);
+ object->runtime.crazyspace_verts_num);
return;
}
diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc
index 354ddd7d167..8b58ad848f2 100644
--- a/source/blender/blenkernel/intern/curve.cc
+++ b/source/blender/blenkernel/intern/curve.cc
@@ -4718,11 +4718,11 @@ static NURBSValidationStatus nurb_check_valid(const int pnts,
if (pnts <= 1) {
return NURBSValidationStatus::AtLeastTwoPointsRequired;
}
- else if (type == CU_NURBS) {
+ if (type == CU_NURBS) {
if (pnts < order) {
return NURBSValidationStatus::MorePointsThanOrderRequired;
}
- else if (flag & CU_NURB_BEZIER) {
+ if (flag & CU_NURB_BEZIER) {
int points_needed = 0;
if (flag & CU_NURB_CYCLIC) {
const int remainder = pnts % (order - 1);
@@ -4765,7 +4765,7 @@ bool BKE_nurb_valid_message(const int pnts,
message_dst[0] = 0;
return false;
}
- msg_template = TIP_("At least two points required.");
+ msg_template = TIP_("At least two points required");
break;
case NURBSValidationStatus::MorePointsThanOrderRequired:
msg_template = TIP_("Must have more control points than Order");
diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc
index 52a2674ab3d..b11216983b2 100644
--- a/source/blender/blenkernel/intern/curve_bezier.cc
+++ b/source/blender/blenkernel/intern/curve_bezier.cc
@@ -121,8 +121,8 @@ void calculate_evaluated_positions(const Span<float3> positions,
});
/* Evaluate the final cyclic segment if necessary. */
- const IndexRange evaluated_range = offsets_to_range(evaluated_offsets, positions.size() - 2);
- if (evaluated_range.size() == 1) {
+ const IndexRange last_segment_points = offsets_to_range(evaluated_offsets, positions.size() - 2);
+ if (last_segment_points.size() == 1) {
evaluated_positions.last() = positions.last();
}
else {
@@ -130,10 +130,54 @@ void calculate_evaluated_positions(const Span<float3> positions,
handles_right.last(),
handles_left.first(),
positions.first(),
- evaluated_positions.slice(evaluated_range));
+ evaluated_positions.slice(last_segment_points));
}
}
+template<typename T>
+static inline void linear_interpolation(const T &a, const T &b, MutableSpan<T> dst)
+{
+ dst.first() = a;
+ const float step = 1.0f / dst.size();
+ for (const int i : dst.index_range().drop_front(1)) {
+ dst[i] = attribute_math::mix2(i * step, a, b);
+ }
+}
+
+template<typename T>
+static void interpolate_to_evaluated(const Span<T> src,
+ const Span<int> evaluated_offsets,
+ MutableSpan<T> dst)
+{
+ BLI_assert(!src.is_empty());
+ BLI_assert(dst.size() == src.size());
+ BLI_assert(evaluated_offsets.last() == dst.size());
+
+ linear_interpolation(src.first(), src[1], dst.take_front(evaluated_offsets.first()));
+
+ threading::parallel_for(
+ src.index_range().drop_back(1).drop_front(1), 512, [&](IndexRange range) {
+ for (const int i : range) {
+ const IndexRange segment_points = offsets_to_range(evaluated_offsets, i - 1);
+ linear_interpolation(src[i], src[i + 1], dst.slice(segment_points));
+ }
+ });
+
+ const IndexRange last_segment_points(evaluated_offsets.last(1),
+ evaluated_offsets.last() - evaluated_offsets.last(1));
+ linear_interpolation(src.last(), src.first(), dst.slice(last_segment_points));
+}
+
+void interpolate_to_evaluated(const GSpan src, const Span<int> evaluated_offsets, GMutableSpan dst)
+{
+ attribute_math::convert_to_static_type(src.type(), [&](auto dummy) {
+ using T = decltype(dummy);
+ if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
+ interpolate_to_evaluated(src.typed<T>(), evaluated_offsets, dst.typed<T>());
+ }
+ });
+}
+
/** \} */
} // namespace blender::bke::curves::bezier
diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc
index 27687eb736f..ea3672dd56b 100644
--- a/source/blender/blenkernel/intern/curve_catmull_rom.cc
+++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc
@@ -9,11 +9,11 @@
namespace blender::bke::curves::catmull_rom {
-int calculate_evaluated_size(const int size, const bool cyclic, const int resolution)
+int calculate_evaluated_size(const int points_num, const bool cyclic, const int resolution)
{
- const int eval_size = resolution * curve_segment_size(size, cyclic);
+ const int eval_size = resolution * curve_segment_size(points_num, cyclic);
/* If the curve isn't cyclic, one last point is added to the final point. */
- return (cyclic && size > 2) ? eval_size : eval_size + 1;
+ return (cyclic && points_num > 2) ? eval_size : eval_size + 1;
}
/* Adapted from Cycles #catmull_rom_basis_eval function. */
diff --git a/source/blender/blenkernel/intern/curve_eval.cc b/source/blender/blenkernel/intern/curve_eval.cc
index b2399f25638..2cf83b57881 100644
--- a/source/blender/blenkernel/intern/curve_eval.cc
+++ b/source/blender/blenkernel/intern/curve_eval.cc
@@ -398,7 +398,7 @@ std::unique_ptr<CurveEval> curves_to_curve_eval(const Curves &curves)
VArray<int8_t> curve_types = geometry.curve_types();
std::unique_ptr<CurveEval> curve_eval = std::make_unique<CurveEval>();
for (const int curve_index : curve_types.index_range()) {
- const IndexRange point_range = geometry.range_for_curve(curve_index);
+ const IndexRange point_range = geometry.points_for_curve(curve_index);
std::unique_ptr<Spline> spline;
switch (curve_types[curve_index]) {
@@ -489,7 +489,7 @@ Curves *curve_eval_to_curves(const CurveEval &curve_eval)
const Spline &spline = *curve_eval.splines()[curve_index];
curve_types[curve_index] = curve_eval.splines()[curve_index]->type();
- const IndexRange point_range = geometry.range_for_curve(curve_index);
+ const IndexRange point_range = geometry.points_for_curve(curve_index);
switch (spline.type()) {
case CURVE_TYPE_POLY:
diff --git a/source/blender/blenkernel/intern/curve_nurbs.cc b/source/blender/blenkernel/intern/curve_nurbs.cc
index a4cdbbca654..0114c0b45f4 100644
--- a/source/blender/blenkernel/intern/curve_nurbs.cc
+++ b/source/blender/blenkernel/intern/curve_nurbs.cc
@@ -10,53 +10,53 @@
namespace blender::bke::curves::nurbs {
-bool check_valid_size_and_order(const int size,
+bool check_valid_size_and_order(const int points_num,
const int8_t order,
const bool cyclic,
const KnotsMode knots_mode)
{
- if (size < order) {
+ if (points_num < order) {
return false;
}
if (ELEM(knots_mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER)) {
- if (knots_mode == NURBS_KNOT_MODE_BEZIER && size <= order) {
+ if (knots_mode == NURBS_KNOT_MODE_BEZIER && points_num <= order) {
return false;
}
- return (!cyclic || size % (order - 1) == 0);
+ return (!cyclic || points_num % (order - 1) == 0);
}
return true;
}
-int calculate_evaluated_size(const int size,
+int calculate_evaluated_size(const int points_num,
const int8_t order,
const bool cyclic,
const int resolution,
const KnotsMode knots_mode)
{
- if (!check_valid_size_and_order(size, order, cyclic, knots_mode)) {
+ if (!check_valid_size_and_order(points_num, order, cyclic, knots_mode)) {
return 0;
}
- return resolution * curve_segment_size(size, cyclic);
+ return resolution * curve_segment_size(points_num, cyclic);
}
-int knots_size(const int size, const int8_t order, const bool cyclic)
+int knots_size(const int points_num, const int8_t order, const bool cyclic)
{
if (cyclic) {
- return size + order * 2 - 1;
+ return points_num + order * 2 - 1;
}
- return size + order;
+ return points_num + order;
}
-void calculate_knots(const int size,
+void calculate_knots(const int points_num,
const KnotsMode mode,
const int8_t order,
const bool cyclic,
MutableSpan<float> knots)
{
- BLI_assert(knots.size() == knots_size(size, order, cyclic));
- UNUSED_VARS_NDEBUG(size);
+ BLI_assert(knots.size() == knots_size(points_num, order, cyclic));
+ UNUSED_VARS_NDEBUG(points_num);
const bool is_bezier = ELEM(mode, NURBS_KNOT_MODE_BEZIER, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
const bool is_end_point = ELEM(mode, NURBS_KNOT_MODE_ENDPOINT, NURBS_KNOT_MODE_ENDPOINT_BEZIER);
@@ -94,7 +94,7 @@ void calculate_knots(const int size,
}
static void calculate_basis_for_point(const float parameter,
- const int size,
+ const int points_num,
const int degree,
const Span<float> knots,
MutableSpan<float> r_weights,
@@ -104,7 +104,7 @@ static void calculate_basis_for_point(const float parameter,
int start = 0;
int end = 0;
- for (const int i : IndexRange(size + degree)) {
+ for (const int i : IndexRange(points_num + degree)) {
const bool knots_equal = knots[i] == knots[i + 1];
if (knots_equal || parameter < knots[i] || parameter > knots[i + 1]) {
continue;
@@ -121,7 +121,7 @@ static void calculate_basis_for_point(const float parameter,
for (const int i_order : IndexRange(2, degree)) {
if (end + i_order >= knots.size()) {
- end = size + degree - i_order;
+ end = points_num + degree - i_order;
}
for (const int i : IndexRange(end - start + 1)) {
const int knot_index = start + i;
@@ -146,15 +146,14 @@ static void calculate_basis_for_point(const float parameter,
r_start_index = start;
}
-void calculate_basis_cache(const int size,
+void calculate_basis_cache(const int points_num,
const int evaluated_size,
const int8_t order,
const bool cyclic,
const Span<float> knots,
BasisCache &basis_cache)
{
- BLI_assert(size > 0);
- BLI_assert(evaluated_size > 0);
+ BLI_assert(points_num > 0);
const int8_t degree = order - 1;
@@ -168,7 +167,7 @@ void calculate_basis_cache(const int size,
MutableSpan<float> basis_weights(basis_cache.weights);
MutableSpan<int> basis_start_indices(basis_cache.start_indices);
- const int last_control_point_index = cyclic ? size + degree : size;
+ const int last_control_point_index = cyclic ? points_num + degree : points_num;
const int evaluated_segment_size = curve_segment_size(evaluated_size, cyclic);
const float start = knots[degree];
@@ -176,7 +175,7 @@ void calculate_basis_cache(const int size,
const float step = (end - start) / evaluated_segment_size;
for (const int i : IndexRange(evaluated_size)) {
/* Clamp parameter due to floating point inaccuracy. */
- const float parameter = std::clamp(start + step * i, knots[0], knots[size + degree]);
+ const float parameter = std::clamp(start + step * i, knots[0], knots[points_num + degree]);
MutableSpan<float> point_weights = basis_weights.slice(i * order, order);
diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc
index 838f7f28e93..82db1176759 100644
--- a/source/blender/blenkernel/intern/curves.cc
+++ b/source/blender/blenkernel/intern/curves.cc
@@ -366,19 +366,19 @@ void BKE_curves_batch_cache_free(Curves *curves)
namespace blender::bke {
-Curves *curves_new_nomain(const int point_size, const int curves_size)
+Curves *curves_new_nomain(const int points_num, const int curves_num)
{
Curves *curves = static_cast<Curves *>(BKE_id_new_nomain(ID_CV, nullptr));
CurvesGeometry &geometry = CurvesGeometry::wrap(curves->geometry);
- geometry.resize(point_size, curves_size);
+ geometry.resize(points_num, curves_num);
return curves;
}
-Curves *curves_new_nomain_single(const int point_size, const CurveType type)
+Curves *curves_new_nomain_single(const int points_num, const CurveType type)
{
- Curves *curves = curves_new_nomain(point_size, 1);
+ Curves *curves = curves_new_nomain(points_num, 1);
CurvesGeometry &geometry = CurvesGeometry::wrap(curves->geometry);
- geometry.offsets().last() = point_size;
+ geometry.offsets().last() = points_num;
geometry.curve_types().first() = type;
return curves;
}
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc
index db69fbc4063..7ceaa8f0f37 100644
--- a/source/blender/blenkernel/intern/curves_geometry.cc
+++ b/source/blender/blenkernel/intern/curves_geometry.cc
@@ -149,24 +149,24 @@ CurvesGeometry::~CurvesGeometry()
/** \name Accessors
* \{ */
-int CurvesGeometry::points_size() const
+int CurvesGeometry::points_num() const
{
return this->point_size;
}
-int CurvesGeometry::curves_size() const
+int CurvesGeometry::curves_num() const
{
return this->curve_size;
}
IndexRange CurvesGeometry::points_range() const
{
- return IndexRange(this->points_size());
+ return IndexRange(this->points_num());
}
IndexRange CurvesGeometry::curves_range() const
{
- return IndexRange(this->curves_size());
+ return IndexRange(this->curves_num());
}
-IndexRange CurvesGeometry::range_for_curve(const int index) const
+IndexRange CurvesGeometry::points_for_curve(const int index) const
{
BLI_assert(this->curve_size > 0);
BLI_assert(this->curve_offsets != nullptr);
@@ -175,7 +175,7 @@ IndexRange CurvesGeometry::range_for_curve(const int index) const
return {offset, offset_next - offset};
}
-IndexRange CurvesGeometry::range_for_curves(const IndexRange curves) const
+IndexRange CurvesGeometry::points_for_curves(const IndexRange curves) const
{
BLI_assert(this->curve_size > 0);
BLI_assert(this->curve_offsets != nullptr);
@@ -186,7 +186,7 @@ IndexRange CurvesGeometry::range_for_curves(const IndexRange curves) const
static int domain_size(const CurvesGeometry &curves, const AttributeDomain domain)
{
- return domain == ATTR_DOMAIN_POINT ? curves.points_size() : curves.curves_size();
+ return domain == ATTR_DOMAIN_POINT ? curves.points_num() : curves.curves_num();
}
static CustomData &domain_custom_data(CurvesGeometry &curves, const AttributeDomain domain)
@@ -277,6 +277,40 @@ bool CurvesGeometry::has_curve_with_type(const CurveType type) const
return false;
}
+std::array<int, CURVE_TYPES_NUM> CurvesGeometry::count_curve_types() const
+{
+ using CountsType = std::array<int, CURVE_TYPES_NUM>;
+
+ CountsType identity;
+ identity.fill(0);
+
+ const VArray<int8_t> types = this->curve_types();
+ if (types.is_single()) {
+ identity[types.get_internal_single()] = this->curves_num();
+ return identity;
+ }
+
+ Span<int8_t> types_span = types.get_internal_span();
+ return threading::parallel_reduce(
+ this->curves_range(),
+ 2048,
+ identity,
+ [&](const IndexRange curves_range, const CountsType &init) {
+ CountsType result = init;
+ for (const int curve_index : curves_range) {
+ result[types_span[curve_index]]++;
+ }
+ return result;
+ },
+ [](const CountsType &a, const CountsType &b) {
+ CountsType result = a;
+ for (const int i : IndexRange(CURVE_TYPES_NUM)) {
+ result[i] += b[i];
+ }
+ return result;
+ });
+}
+
MutableSpan<float3> CurvesGeometry::positions()
{
this->position = (float(*)[3])CustomData_duplicate_referenced_layer_named(
@@ -431,7 +465,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
VArray<int8_t> nurbs_knots_modes = curves.nurbs_knots_modes();
build_offsets(offsets, [&](const int curve_index) -> int {
- const IndexRange points = curves.range_for_curve(curve_index);
+ const IndexRange points = curves.points_for_curve(curve_index);
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
return curves::catmull_rom::calculate_evaluated_size(
@@ -457,35 +491,44 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves,
});
}
-int CurvesGeometry::evaluated_points_size() const
+int CurvesGeometry::evaluated_points_num() const
{
/* This could avoid calculating offsets in the future in simple circumstances. */
return this->evaluated_offsets().last();
}
-IndexRange CurvesGeometry::evaluated_range_for_curve(int index) const
+IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const
{
BLI_assert(!this->runtime->offsets_cache_dirty);
return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index);
}
-Span<int> CurvesGeometry::evaluated_offsets() const
+IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const
+{
+ BLI_assert(!this->runtime->offsets_cache_dirty);
+ BLI_assert(this->curve_size > 0);
+ const int offset = this->runtime->evaluated_offsets_cache[curves.start()];
+ const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()];
+ return {offset, offset_next - offset};
+}
+
+void CurvesGeometry::ensure_evaluated_offsets() const
{
if (!this->runtime->offsets_cache_dirty) {
- return this->runtime->evaluated_offsets_cache;
+ return;
}
/* A double checked lock. */
std::scoped_lock lock{this->runtime->offsets_cache_mutex};
if (!this->runtime->offsets_cache_dirty) {
- return this->runtime->evaluated_offsets_cache;
+ return;
}
threading::isolate_task([&]() {
- this->runtime->evaluated_offsets_cache.resize(this->curves_size() + 1);
+ this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1);
if (this->has_curve_with_type(CURVE_TYPE_BEZIER)) {
- this->runtime->bezier_evaluated_offsets.resize(this->points_size());
+ this->runtime->bezier_evaluated_offsets.resize(this->points_num());
}
else {
this->runtime->bezier_evaluated_offsets.clear_and_make_inline();
@@ -496,6 +539,11 @@ Span<int> CurvesGeometry::evaluated_offsets() const
});
this->runtime->offsets_cache_dirty = false;
+}
+
+Span<int> CurvesGeometry::evaluated_offsets() const
+{
+ this->ensure_evaluated_offsets();
return this->runtime->evaluated_offsets_cache;
}
@@ -536,7 +584,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
return;
}
- this->runtime->nurbs_basis_cache.resize(this->curves_size());
+ this->runtime->nurbs_basis_cache.resize(this->curves_num());
MutableSpan<curves::nurbs::BasisCache> basis_caches(this->runtime->nurbs_basis_cache);
VArray<bool> cyclic = this->cyclic();
@@ -545,8 +593,8 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) {
for (const int curve_index : nurbs_mask.slice(range)) {
- const IndexRange points = this->range_for_curve(curve_index);
- const IndexRange evaluated_points = this->evaluated_range_for_curve(curve_index);
+ const IndexRange points = this->points_for_curve(curve_index);
+ const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
const int8_t order = orders[curve_index];
const bool is_cyclic = cyclic[curve_index];
@@ -564,6 +612,8 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const
}
});
});
+
+ this->runtime->nurbs_basis_cache_dirty = false;
}
Span<float3> CurvesGeometry::evaluated_positions() const
@@ -579,7 +629,7 @@ Span<float3> CurvesGeometry::evaluated_positions() const
}
threading::isolate_task([&]() {
- this->runtime->evaluated_position_cache.resize(this->evaluated_points_size());
+ this->runtime->evaluated_position_cache.resize(this->evaluated_points_num());
MutableSpan<float3> evaluated_positions = this->runtime->evaluated_position_cache;
VArray<int8_t> types = this->curve_types();
@@ -598,8 +648,8 @@ Span<float3> CurvesGeometry::evaluated_positions() const
threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) {
for (const int curve_index : curves_range) {
- const IndexRange points = this->range_for_curve(curve_index);
- const IndexRange evaluated_points = this->evaluated_range_for_curve(curve_index);
+ const IndexRange points = this->points_for_curve(curve_index);
+ const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index);
switch (types[curve_index]) {
case CURVE_TYPE_CATMULL_ROM:
@@ -639,22 +689,54 @@ Span<float3> CurvesGeometry::evaluated_positions() const
return this->runtime->evaluated_position_cache;
}
+void CurvesGeometry::interpolate_to_evaluated(const int curve_index,
+ const GSpan src,
+ GMutableSpan dst) const
+{
+ BLI_assert(!this->runtime->offsets_cache_dirty);
+ BLI_assert(!this->runtime->nurbs_basis_cache_dirty);
+ const IndexRange points = this->points_for_curve(curve_index);
+ BLI_assert(src.size() == points.size());
+ BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size());
+ switch (this->curve_types()[curve_index]) {
+ case CURVE_TYPE_CATMULL_ROM:
+ curves::catmull_rom::interpolate_to_evaluated(
+ src, this->cyclic()[curve_index], this->resolution()[curve_index], dst);
+ return;
+ case CURVE_TYPE_POLY:
+ dst.type().copy_assign_n(src.data(), dst.data(), src.size());
+ return;
+ case CURVE_TYPE_BEZIER:
+ curves::bezier::interpolate_to_evaluated(
+ src, this->runtime->bezier_evaluated_offsets.as_span().slice(points), dst);
+ return;
+ case CURVE_TYPE_NURBS:
+ curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index],
+ this->nurbs_orders()[curve_index],
+ this->nurbs_weights().slice(points),
+ src,
+ dst);
+ return;
+ }
+ BLI_assert_unreachable();
+}
+
/** \} */
/* -------------------------------------------------------------------- */
/** \name Operations
* \{ */
-void CurvesGeometry::resize(const int point_size, const int curve_size)
+void CurvesGeometry::resize(const int points_num, const int curves_num)
{
- if (point_size != this->point_size) {
- CustomData_realloc(&this->point_data, point_size);
- this->point_size = point_size;
+ if (points_num != this->point_size) {
+ CustomData_realloc(&this->point_data, points_num);
+ this->point_size = points_num;
}
- if (curve_size != this->curve_size) {
- CustomData_realloc(&this->curve_data, curve_size);
- this->curve_size = curve_size;
- this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curve_size + 1));
+ if (curves_num != this->curve_size) {
+ CustomData_realloc(&this->curve_data, curves_num);
+ this->curve_size = curves_num;
+ this->curve_offsets = (int *)MEM_reallocN(this->curve_offsets, sizeof(int) * (curves_num + 1));
}
this->tag_topology_changed();
this->update_customdata_pointers();
@@ -727,7 +809,7 @@ static std::optional<bounds::MinMaxResult<float3>> curves_bounds(const CurvesGeo
{
Span<float3> positions = curves.positions();
if (curves.radius) {
- Span<float> radii{curves.radius, curves.points_size()};
+ Span<float> radii{curves.radius, curves.points_num()};
return bounds::min_max_with_radii(positions, radii);
}
return bounds::min_max(positions);
@@ -784,7 +866,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves,
new_curve_ranges.append(IndexRange(new_tot_curves, curve_range.size()));
new_tot_curves += curve_range.size();
- const IndexRange old_point_range = curves.range_for_curves(curve_range);
+ const IndexRange old_point_range = curves.points_for_curves(curve_range);
old_point_ranges.append(old_point_range);
new_point_ranges.append(IndexRange(new_tot_points, old_point_range.size()));
new_tot_points += old_point_range.size();
@@ -889,7 +971,7 @@ static void reverse_curve_point_data(const CurvesGeometry &curves,
{
threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) {
for (const int curve_i : curve_selection.slice(range)) {
- data.slice(curves.range_for_curve(curve_i)).reverse();
+ data.slice(curves.points_for_curve(curve_i)).reverse();
}
});
}
@@ -902,7 +984,7 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves,
{
threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) {
for (const int curve_i : curve_selection.slice(range)) {
- const IndexRange points = curves.range_for_curve(curve_i);
+ const IndexRange points = curves.points_for_curve(curve_i);
MutableSpan<T> a = data_a.slice(points);
MutableSpan<T> b = data_b.slice(points);
for (const int i : IndexRange(points.size() / 2)) {
@@ -926,7 +1008,7 @@ static bool layer_matches_name_and_type(const CustomDataLayer &layer,
void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
{
- CustomData_duplicate_referenced_layers(&this->point_data, this->points_size());
+ CustomData_duplicate_referenced_layers(&this->point_data, this->points_num());
/* Collect the Bezier handle attributes while iterating through the point custom data layers;
* they need special treatment later. */
@@ -940,22 +1022,22 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
if (positions_left.is_empty() &&
layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_LEFT, CD_PROP_FLOAT3)) {
- positions_left = {static_cast<float3 *>(layer.data), this->points_size()};
+ positions_left = {static_cast<float3 *>(layer.data), this->points_num()};
continue;
}
if (positions_right.is_empty() &&
layer_matches_name_and_type(layer, ATTR_HANDLE_POSITION_RIGHT, CD_PROP_FLOAT3)) {
- positions_right = {static_cast<float3 *>(layer.data), this->points_size()};
+ positions_right = {static_cast<float3 *>(layer.data), this->points_num()};
continue;
}
if (types_left.is_empty() &&
layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_LEFT, CD_PROP_INT8)) {
- types_left = {static_cast<int8_t *>(layer.data), this->points_size()};
+ types_left = {static_cast<int8_t *>(layer.data), this->points_num()};
continue;
}
if (types_right.is_empty() &&
layer_matches_name_and_type(layer, ATTR_HANDLE_TYPE_RIGHT, CD_PROP_INT8)) {
- types_right = {static_cast<int8_t *>(layer.data), this->points_size()};
+ types_right = {static_cast<int8_t *>(layer.data), this->points_num()};
continue;
}
@@ -963,7 +1045,7 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse)
attribute_math::convert_to_static_type(data_type, [&](auto dummy) {
using T = decltype(dummy);
reverse_curve_point_data<T>(
- *this, curves_to_reverse, {static_cast<T *>(layer.data), this->points_size()});
+ *this, curves_to_reverse, {static_cast<T *>(layer.data), this->points_num()});
});
}
@@ -1001,8 +1083,8 @@ static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves,
MutableSpan<T> r_values)
{
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int i_curve : IndexRange(curves.curves_size())) {
- for (const int i_point : curves.range_for_curve(i_curve)) {
+ for (const int i_curve : IndexRange(curves.curves_num())) {
+ for (const int i_point : curves.points_for_curve(i_curve)) {
mixer.mix_in(i_curve, old_values[i_point]);
}
}
@@ -1022,8 +1104,8 @@ void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves,
MutableSpan<bool> r_values)
{
r_values.fill(true);
- for (const int i_curve : IndexRange(curves.curves_size())) {
- for (const int i_point : curves.range_for_curve(i_curve)) {
+ for (const int i_curve : IndexRange(curves.curves_num())) {
+ for (const int i_point : curves.points_for_curve(i_curve)) {
if (!old_values[i_point]) {
r_values[i_curve] = false;
break;
@@ -1039,7 +1121,7 @@ static GVArray adapt_curve_domain_point_to_curve(const CurvesGeometry &curves,
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
- Array<T> values(curves.curves_size());
+ Array<T> values(curves.curves_num());
adapt_curve_domain_point_to_curve_impl<T>(curves, varray.typed<T>(), values);
new_varray = VArray<T>::ForContainer(std::move(values));
}
@@ -1059,8 +1141,8 @@ static void adapt_curve_domain_curve_to_point_impl(const CurvesGeometry &curves,
const VArray<T> &old_values,
MutableSpan<T> r_values)
{
- for (const int i_curve : IndexRange(curves.curves_size())) {
- r_values.slice(curves.range_for_curve(i_curve)).fill(old_values[i_curve]);
+ for (const int i_curve : IndexRange(curves.curves_num())) {
+ r_values.slice(curves.points_for_curve(i_curve)).fill(old_values[i_curve]);
}
}
@@ -1070,7 +1152,7 @@ static GVArray adapt_curve_domain_curve_to_point(const CurvesGeometry &curves,
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
- Array<T> values(curves.points_size());
+ Array<T> values(curves.points_num());
adapt_curve_domain_curve_to_point_impl<T>(curves, varray.typed<T>(), values);
new_varray = VArray<T>::ForContainer(std::move(values));
});
diff --git a/source/blender/blenkernel/intern/curves_geometry_test.cc b/source/blender/blenkernel/intern/curves_geometry_test.cc
index 1b3b3f54451..e4dc9eead60 100644
--- a/source/blender/blenkernel/intern/curves_geometry_test.cc
+++ b/source/blender/blenkernel/intern/curves_geometry_test.cc
@@ -46,7 +46,7 @@ TEST(curves_geometry, Move)
CurvesGeometry other = std::move(curves);
/* The old curves should be empty, and the offsets are expected to be null. */
- EXPECT_EQ(curves.points_size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(curves.points_num(), 0); /* NOLINT: bugprone-use-after-move */
EXPECT_EQ(curves.curve_offsets, nullptr); /* NOLINT: bugprone-use-after-move */
/* Just a basic check that the new curves work okay. */
@@ -63,6 +63,28 @@ TEST(curves_geometry, Move)
EXPECT_EQ(second_other.offsets().data(), offsets_data);
}
+TEST(curves_geometry, TypeCount)
+{
+ CurvesGeometry curves = create_basic_curves(100, 10);
+ curves.curve_types().copy_from({
+ CURVE_TYPE_BEZIER,
+ CURVE_TYPE_NURBS,
+ CURVE_TYPE_NURBS,
+ CURVE_TYPE_NURBS,
+ CURVE_TYPE_CATMULL_ROM,
+ CURVE_TYPE_CATMULL_ROM,
+ CURVE_TYPE_CATMULL_ROM,
+ CURVE_TYPE_POLY,
+ CURVE_TYPE_POLY,
+ CURVE_TYPE_POLY,
+ });
+ std::array<int, CURVE_TYPES_NUM> counts = curves.count_curve_types();
+ EXPECT_EQ(counts[CURVE_TYPE_CATMULL_ROM], 3);
+ EXPECT_EQ(counts[CURVE_TYPE_POLY], 3);
+ EXPECT_EQ(counts[CURVE_TYPE_BEZIER], 1);
+ EXPECT_EQ(counts[CURVE_TYPE_NURBS], 3);
+}
+
TEST(curves_geometry, CatmullRomEvaluation)
{
CurvesGeometry curves(4, 1);
@@ -206,7 +228,7 @@ TEST(curves_geometry, CatmullRomTwoPointCyclic)
/* The cyclic value should be ignored when there are only two control points. There should
* be 12 evaluated points for the single segment and an extra for the last point. */
- EXPECT_EQ(curves.evaluated_points_size(), 13);
+ EXPECT_EQ(curves.evaluated_points_num(), 13);
}
TEST(curves_geometry, BezierPositionEvaluation)
@@ -383,4 +405,77 @@ TEST(curves_geometry, NURBSEvaluation)
}
}
+TEST(curves_geometry, BezierGenericEvaluation)
+{
+ CurvesGeometry curves(3, 1);
+ curves.curve_types().fill(CURVE_TYPE_BEZIER);
+ curves.resolution().fill(8);
+ curves.offsets().last() = 3;
+
+ MutableSpan<float3> handles_left = curves.handle_positions_left();
+ MutableSpan<float3> handles_right = curves.handle_positions_right();
+ MutableSpan<float3> positions = curves.positions();
+ positions.first() = {-1, 0, 0};
+ handles_right.first() = {-1, 1, 0};
+ handles_left[1] = {0, 0, 0};
+ positions[1] = {1, 0, 0};
+ handles_right[1] = {2, 0, 0};
+ handles_left.last() = {1, 1, 0};
+ positions.last() = {2, 1, 0};
+
+ /* Dangling handles shouldn't be used in a non-cyclic curve. */
+ handles_left.first() = {100, 100, 100};
+ handles_right.last() = {100, 100, 100};
+
+ Span<float3> evaluated_positions = curves.evaluated_positions();
+ static const Array<float3> result_1{{
+ {-1.0f, 0.0f, 0.0f},
+ {-0.955078f, 0.287109f, 0.0f},
+ {-0.828125f, 0.421875f, 0.0f},
+ {-0.630859f, 0.439453f, 0.0f},
+ {-0.375f, 0.375f, 0.0f},
+ {-0.0722656f, 0.263672f, 0.0f},
+ {0.265625f, 0.140625f, 0.0f},
+ {0.626953f, 0.0410156f, 0.0f},
+ {1.0f, 0.0f, 0.0f},
+ {1.28906f, 0.0429688f, 0.0f},
+ {1.4375f, 0.15625f, 0.0f},
+ {1.49219f, 0.316406f, 0.0f},
+ {1.5f, 0.5f, 0.0f},
+ {1.50781f, 0.683594f, 0.0f},
+ {1.5625f, 0.84375f, 0.0f},
+ {1.71094f, 0.957031f, 0.0f},
+ {2.0f, 1.0f, 0.0f},
+ }};
+ for (const int i : evaluated_positions.index_range()) {
+ EXPECT_V3_NEAR(evaluated_positions[i], result_1[i], 1e-5f);
+ }
+
+ Array<float> radii{{0.0f, 1.0f, 2.0f}};
+ Array<float> evaluated_radii(17);
+ curves.interpolate_to_evaluated(0, radii.as_span(), evaluated_radii.as_mutable_span());
+ static const Array<float> result_2{{
+ 0.0f,
+ 0.125f,
+ 0.25f,
+ 0.375f,
+ 0.5f,
+ 0.625f,
+ 0.75f,
+ 0.875f,
+ 1.0f,
+ 1.125f,
+ 1.25f,
+ 1.375f,
+ 1.5f,
+ 1.625f,
+ 1.75f,
+ 1.875f,
+ 2.0f,
+ }};
+ for (const int i : evaluated_radii.index_range()) {
+ EXPECT_NEAR(evaluated_radii[i], result_2[i], 1e-6f);
+ }
+}
+
} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index e5424b39091..702488fb93b 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -62,6 +62,10 @@ BLI_STATIC_ASSERT(ARRAY_SIZE(((CustomData *)nullptr)->typemap) == CD_NUMTYPES, "
static CLG_LogRef LOG = {"bke.customdata"};
+/* -------------------------------------------------------------------- */
+/** \name Mesh Mask Utilities
+ * \{ */
+
void CustomData_MeshMasks_update(CustomData_MeshMasks *mask_dst,
const CustomData_MeshMasks *mask_src)
{
@@ -82,7 +86,12 @@ bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref,
((mask_required->lmask & mask_ref->lmask) == mask_required->lmask));
}
-/********************* Layer type information **********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Layer Type Information
+ * \{ */
+
struct LayerTypeInfo {
int size; /* the memory size of one element of this layer's data */
@@ -164,6 +173,12 @@ struct LayerTypeInfo {
int (*layers_max)();
};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MDeformVert, #CD_MDEFORMVERT)
+ * \{ */
+
static void layerCopy_mdeformvert(const void *source, void *dest, int count)
{
int i, size = sizeof(MDeformVert);
@@ -315,6 +330,12 @@ static void layerInterp_mdeformvert(const void **sources,
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#vec3f, #CD_NORMAL)
+ * \{ */
+
static void layerInterp_normal(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
@@ -371,6 +392,12 @@ static void layerCopyValue_normal(const void *source,
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MTFace, #CD_MTFACE)
+ * \{ */
+
static void layerCopy_tface(const void *source, void *dest, int count)
{
const MTFace *source_tf = (const MTFace *)source;
@@ -436,6 +463,12 @@ static int layerMaxNum_tface()
return MAX_MTFACE;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MFloatProperty, #CD_PROP_FLOAT)
+ * \{ */
+
static void layerCopy_propFloat(const void *source, void *dest, int count)
{
memcpy(dest, source, sizeof(MFloatProperty) * count);
@@ -473,16 +506,34 @@ static bool layerValidate_propFloat(void *data, const uint totitems, const bool
return has_errors;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MIntProperty, #CD_PROP_INT32)
+ * \{ */
+
static void layerCopy_propInt(const void *source, void *dest, int count)
{
memcpy(dest, source, sizeof(MIntProperty) * count);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MStringProperty, #CD_PROP_STRING)
+ * \{ */
+
static void layerCopy_propString(const void *source, void *dest, int count)
{
memcpy(dest, source, sizeof(MStringProperty) * count);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#OrigSpaceFace, #CD_ORIGSPACE)
+ * \{ */
+
static void layerCopy_origspace_face(const void *source, void *dest, int count)
{
const OrigSpaceFace *source_tf = (const OrigSpaceFace *)source;
@@ -541,6 +592,12 @@ static void layerDefault_origspace_face(void *data, int count)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MDisps, #CD_MDISPS)
+ * \{ */
+
static void layerSwap_mdisps(void *data, const int *ci)
{
MDisps *s = static_cast<MDisps *>(data);
@@ -653,6 +710,13 @@ static size_t layerFilesize_mdisps(CDataFile *UNUSED(cdf), const void *data, int
return size;
}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (`float`, #CD_PAINT_MASK)
+ * \{ */
+
static void layerInterp_paint_mask(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
@@ -668,6 +732,12 @@ static void layerInterp_paint_mask(const void **sources,
*(float *)dest = mask;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#GridPaintMask, #CD_GRID_PAINT_MASK)
+ * \{ */
+
static void layerCopy_grid_paint_mask(const void *source, void *dest, int count)
{
const GridPaintMask *s = static_cast<const GridPaintMask *>(source);
@@ -1179,6 +1249,12 @@ static void layerInterp_shapekey(const void **sources,
copy_v3_v3((float *)dest, co);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MVertSkin, #CD_MVERT_SKIN)
+ * \{ */
+
static void layerDefault_mvert_skin(void *data, int count)
{
MVertSkin *vs = static_cast<MVertSkin *>(data);
@@ -1216,6 +1292,12 @@ static void layerInterp_mvert_skin(const void **sources,
vs_dst->flag &= ~MVERT_SKIN_ROOT;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (`short[4][3]`, #CD_TESSLOOPNORMAL)
+ * \{ */
+
static void layerSwap_flnor(void *data, const int *corner_indices)
{
short(*flnors)[4][3] = static_cast<short(*)[4][3]>(data);
@@ -1229,6 +1311,12 @@ static void layerSwap_flnor(void *data, const int *corner_indices)
memcpy(flnors, nors, sizeof(nors));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (`int`, #CD_FACEMAP)
+ * \{ */
+
static void layerDefault_fmap(void *data, int count)
{
int *fmap_num = (int *)data;
@@ -1237,6 +1325,12 @@ static void layerDefault_fmap(void *data, int count)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#MPropCol, #CD_PROP_COLOR)
+ * \{ */
+
static void layerCopyValue_propcol(const void *source,
void *dest,
const int mixmode,
@@ -1360,6 +1454,12 @@ static int layerMaxNum_propcol()
return MAX_MCOL;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#vec3f, #CD_PROP_FLOAT3)
+ * \{ */
+
static void layerInterp_propfloat3(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
@@ -1407,6 +1507,12 @@ static bool layerValidate_propfloat3(void *data, const uint totitems, const bool
return has_errors;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (#vec2f, #CD_PROP_FLOAT2)
+ * \{ */
+
static void layerInterp_propfloat2(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
@@ -1452,6 +1558,12 @@ static bool layerValidate_propfloat2(void *data, const uint totitems, const bool
return has_errors;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Callbacks for (`bool`, #CD_PROP_BOOL)
+ * \{ */
+
static void layerInterp_propbool(const void **sources,
const float *weights,
const float *UNUSED(sub_weights),
@@ -2053,7 +2165,12 @@ void customData_mask_layers__print(const CustomData_MeshMasks *mask)
}
}
-/********************* CustomData functions *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name CustomData Functions
+ * \{ */
+
static void customData_update_offsets(CustomData *data);
static CustomDataLayer *customData_add_layer__internal(CustomData *data,
@@ -4471,14 +4588,18 @@ void CustomData_layers__print(CustomData *data)
printf("}\n");
}
-/****************************** External Files *******************************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name External Files
+ * \{ */
-static void customdata_external_filename(char filename[FILE_MAX],
+static void customdata_external_filename(char filepath[FILE_MAX],
ID *id,
CustomDataExternal *external)
{
- BLI_strncpy(filename, external->filename, FILE_MAX);
- BLI_path_abs(filename, ID_BLEND_PATH_FROM_GLOBAL(id));
+ BLI_strncpy(filepath, external->filepath, FILE_MAX);
+ BLI_path_abs(filepath, ID_BLEND_PATH_FROM_GLOBAL(id));
}
void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask mask, int totelem)
@@ -4503,7 +4624,7 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
{
CustomDataExternal *external = data->external;
CustomDataLayer *layer;
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
int update = 0;
if (!external) {
@@ -4529,12 +4650,12 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int
return;
}
- customdata_external_filename(filename, id, external);
+ customdata_external_filename(filepath, id, external);
CDataFile *cdf = cdf_create(CDF_TYPE_MESH);
- if (!cdf_read_open(cdf, filename)) {
+ if (!cdf_read_open(cdf, filepath)) {
cdf_free(cdf);
- CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filename);
+ CLOG_ERROR(&LOG, "Failed to read %s layer from %s.", layerType_getName(layer->type), filepath);
return;
}
@@ -4577,7 +4698,7 @@ void CustomData_external_write(
{
CustomDataExternal *external = data->external;
int update = 0;
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
if (!external) {
return;
@@ -4602,7 +4723,7 @@ void CustomData_external_write(
/* make sure data is read before we try to write */
CustomData_external_read(data, id, mask, totelem);
- customdata_external_filename(filename, id, external);
+ customdata_external_filename(filepath, id, external);
CDataFile *cdf = cdf_create(CDF_TYPE_MESH);
@@ -4622,8 +4743,8 @@ void CustomData_external_write(
}
}
- if (!cdf_write_open(cdf, filename)) {
- CLOG_ERROR(&LOG, "Failed to open %s for writing.", filename);
+ if (!cdf_write_open(cdf, filepath)) {
+ CLOG_ERROR(&LOG, "Failed to open %s for writing.", filepath);
cdf_free(cdf);
return;
}
@@ -4651,7 +4772,7 @@ void CustomData_external_write(
}
if (i != data->totlayer) {
- CLOG_ERROR(&LOG, "Failed to write data to %s.", filename);
+ CLOG_ERROR(&LOG, "Failed to write data to %s.", filepath);
cdf_write_close(cdf);
cdf_free(cdf);
return;
@@ -4676,7 +4797,7 @@ void CustomData_external_write(
}
void CustomData_external_add(
- CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filename)
+ CustomData *data, ID *UNUSED(id), int type, int UNUSED(totelem), const char *filepath)
{
CustomDataExternal *external = data->external;
@@ -4695,7 +4816,7 @@ void CustomData_external_add(
external = MEM_cnew<CustomDataExternal>(__func__);
data->external = external;
}
- BLI_strncpy(external->filename, filename, sizeof(external->filename));
+ BLI_strncpy(external->filepath, filepath, sizeof(external->filepath));
layer->flag |= CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY;
}
@@ -4735,7 +4856,12 @@ bool CustomData_external_test(CustomData *data, int type)
return (layer->flag & CD_FLAG_EXTERNAL) != 0;
}
-/* ********** Mesh-to-mesh data transfer ********** */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mesh-to-Mesh Data Transfer
+ * \{ */
+
static void copy_bit_flag(void *dst, const void *src, const size_t data_size, const uint64_t flag)
{
#define COPY_BIT_FLAG(_type, _dst, _src, _f) \
@@ -5014,6 +5140,12 @@ void CustomData_data_transfer(const MeshPairRemap *me_remap,
MEM_SAFE_FREE(tmp_data_src);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Custom Data IO
+ * \{ */
+
static void write_mdisps(BlendWriter *writer, int count, MDisps *mdlist, int external)
{
if (mdlist) {
@@ -5208,6 +5340,12 @@ void CustomData_blend_read(BlendDataReader *reader, CustomData *data, int count)
CustomData_update_typemap(data);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Custom Data Debugging
+ * \{ */
+
#ifndef NDEBUG
void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr)
@@ -5238,8 +5376,16 @@ void CustomData_debug_info_from_layers(const CustomData *data, const char *inden
#endif /* NDEBUG */
+/** \} */
+
namespace blender::bke {
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Custom Data C++ API
+ * \{ */
+
const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type)
{
switch (type) {
@@ -5289,4 +5435,6 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
return static_cast<CustomDataType>(-1);
}
+/** \} */
+
} // namespace blender::bke
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 8ec7bbea0e5..0f5814c0a23 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -3266,7 +3266,7 @@ static void dynamic_paint_output_surface_image_wetmap_cb(
}
void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
- char *filename,
+ const char *filepath,
short output_layer)
{
ImBuf *ibuf = NULL;
@@ -3286,7 +3286,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface,
format = R_IMF_IMTYPE_PNG;
}
#endif
- BLI_strncpy(output_file, filename, sizeof(output_file));
+ BLI_strncpy(output_file, filepath, sizeof(output_file));
BKE_image_path_ensure_ext_from_imtype(output_file, format);
/* Validate output file path */
diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc
index 7cf6fc5a03e..27689d70c77 100644
--- a/source/blender/blenkernel/intern/geometry_component_curves.cc
+++ b/source/blender/blenkernel/intern/geometry_component_curves.cc
@@ -236,10 +236,10 @@ int CurveComponent::attribute_domain_size(const AttributeDomain domain) const
const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(
curves_->geometry);
if (domain == ATTR_DOMAIN_POINT) {
- return geometry.points_size();
+ return geometry.points_num();
}
if (domain == ATTR_DOMAIN_CURVE) {
- return geometry.curves_size();
+ return geometry.curves_num();
}
return 0;
}
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index 76c8a0054b3..2bfe984462c 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -944,20 +944,71 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
if (dverts_ == nullptr) {
return 0.0f;
}
- const MDeformVert &dvert = dverts_[index];
- for (const MDeformWeight &weight : Span(dvert.dw, dvert.totweight)) {
- if (weight.def_nr == dvert_index_) {
- return weight.weight;
- }
+ if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
+ return weight->weight;
}
return 0.0f;
- ;
}
void set(const int64_t index, const float value) override
{
- MDeformWeight *weight = BKE_defvert_ensure_index(&dverts_[index], dvert_index_);
- weight->weight = value;
+ MDeformVert &dvert = dverts_[index];
+ if (value == 0.0f) {
+ if (MDeformWeight *weight = this->find_weight_at_index(index)) {
+ weight->weight = 0.0f;
+ }
+ }
+ else {
+ MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_);
+ weight->weight = value;
+ }
+ }
+
+ void set_all(Span<float> src) override
+ {
+ for (const int64_t index : src.index_range()) {
+ this->set(index, src[index]);
+ }
+ }
+
+ void materialize(IndexMask mask, MutableSpan<float> r_span) const override
+ {
+ if (dverts_ == nullptr) {
+ return r_span.fill_indices(mask, 0.0f);
+ }
+ for (const int64_t index : mask) {
+ if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
+ r_span[index] = weight->weight;
+ }
+ else {
+ r_span[index] = 0.0f;
+ }
+ }
+ }
+
+ void materialize_to_uninitialized(IndexMask mask, MutableSpan<float> r_span) const override
+ {
+ this->materialize(mask, r_span);
+ }
+
+ private:
+ MDeformWeight *find_weight_at_index(const int64_t index)
+ {
+ for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) {
+ if (weight.def_nr == dvert_index_) {
+ return &weight;
+ }
+ }
+ return nullptr;
+ }
+ const MDeformWeight *find_weight_at_index(const int64_t index) const
+ {
+ for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) {
+ if (weight.def_nr == dvert_index_) {
+ return &weight;
+ }
+ }
+ return nullptr;
}
};
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index a5eff1f9d5a..a0b6ab2d654 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -980,74 +980,116 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
/** \name Stroke Smooth Positions
* \{ */
-bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf, const bool smooth_caps)
+bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps,
+ int i,
+ float influence,
+ int iterations,
+ const bool smooth_caps,
+ const bool keep_shape,
+ bGPDstroke *r_gps)
{
- bGPDspoint *pt = &gps->points[i];
- float sco[3] = {0.0f};
- const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
-
- /* Do nothing if not enough points to smooth out */
- if (gps->totpoints <= 2) {
+ /* If nothing to do, return early */
+ if (gps->totpoints <= 2 || iterations <= 0) {
return false;
}
- /* Only affect endpoints by a fraction of the normal strength,
- * to prevent the stroke from shrinking too much
+ /* Overview of the algorithm here and in the following smooth functions:
+ * The smooth functions return the new attribute in question for a single point.
+ * The result is stored in r_gps->points[i], while the data is read from gps.
+ * To get a correct result, duplicate the stroke point data and read from the copy,
+ * while writing to the real stroke. Not doing that will result in acceptable, but
+ * asymmetric results.
+ * This algorithm works as long as all points are being smoothed. If there is
+ * points that should not get smoothed, use the old repeat smooth pattern with
+ * the parameter "iterations" set to 1 or 2. (2 matches the old algorithm).
*/
- if ((!smooth_caps) && (!is_cyclic && ELEM(i, 0, gps->totpoints - 1))) {
- inf *= 0.1f;
- }
-
- /* Compute smoothed coordinate by taking the ones nearby */
- /* XXX: This is potentially slow,
- * and suffers from accumulation error as earlier points are handled before later ones. */
- {
- /* XXX: this is hardcoded to look at 2 points on either side of the current one
- * (i.e. 5 items total). */
- const int steps = 2;
- const float average_fac = 1.0f / (float)(steps * 2 + 1);
- int step;
-
- /* add the point itself */
- madd_v3_v3fl(sco, &pt->x, average_fac);
-
- /* n-steps before/after current point */
- /* XXX: review how the endpoints are treated by this algorithm. */
- /* XXX: falloff measures should also introduce some weighting variations,
- * so that further-out points get less weight. */
- for (step = 1; step <= steps; step++) {
- bGPDspoint *pt1, *pt2;
- int before = i - step;
- int after = i + step;
-
- if (is_cyclic) {
- if (before < 0) {
- /* Sub to end point (before is already negative). */
- before = gps->totpoints + before;
- CLAMP(before, 0, gps->totpoints - 1);
- }
- if (after > gps->totpoints - 1) {
- /* Add to start point. */
- after = after - gps->totpoints;
- CLAMP(after, 0, gps->totpoints - 1);
+
+ const bGPDspoint *pt = &gps->points[i];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
+ /* If smooth_caps is false, the caps will not be translated by smoothing. */
+ if (!smooth_caps && !is_cyclic && ELEM(i, 0, gps->totpoints - 1)) {
+ copy_v3_v3(&r_gps->points[i].x, &pt->x);
+ return true;
+ }
+
+ /* This function uses a binomial kernel, which is the discrete version of gaussian blur.
+ * The weight for a vertex at the relative index i is
+ * w = nCr(n, j + n/2) / 2^n = (n/1 * (n-1)/2 * ... * (n-j-n/2)/(j+n/2)) / 2^n
+ * All weights together sum up to 1
+ * This is equivalent to doing multiple iterations of averaging neighbors,
+ * where n = iterations * 2 and -n/2 <= j <= n/2
+ *
+ * Now the problem is that nCr(n, j + n/2) is very hard to compute for n > 500, since even
+ * double precision isn't sufficient. A very good robust approximation for n > 20 is
+ * nCr(n, j + n/2) / 2^n = sqrt(2/(pi*n)) * exp(-2*j*j/n)
+ *
+ * There is one more problem left: The old smooth algorithm was doing a more aggressive
+ * smooth. To solve that problem, choose a different n/2, which does not match the range and
+ * normalize the weights on finish. This may cause some artifacts at low values.
+ *
+ * keep_shape is a new option to stop the stroke from severly deforming.
+ * It uses different partially negative weights.
+ * w = 2 * (nCr(n, j + n/2) / 2^n) - (nCr(3*n, j + n) / 2^(3*n))
+ * ~ 2 * sqrt(2/(pi*n)) * exp(-2*j*j/n) - sqrt(2/(pi*3*n)) * exp(-2*j*j/(3*n))
+ * All weigths still sum up to 1.
+ * Note these weights only work because the averaging is done in relative coordinates.
+ */
+ float sco[3] = {0.0f, 0.0f, 0.0f};
+ float tmp[3];
+ const int n_half = keep_shape ? (iterations * iterations) / 8 + iterations :
+ (iterations * iterations) / 4 + 2 * iterations + 12;
+ double w = keep_shape ? 2.0 : 1.0;
+ double w2 = keep_shape ?
+ (1.0 / M_SQRT3) * exp((2 * iterations * iterations) / (double)(n_half * 3)) :
+ 0.0;
+ double total_w = 0.0;
+ for (int step = iterations; step > 0; step--) {
+ int before = i - step;
+ int after = i + step;
+ float w_before = (float)(w - w2);
+ float w_after = (float)(w - w2);
+
+ if (is_cyclic) {
+ before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
+ after = after % gps->totpoints;
+ }
+ else {
+ if (before < 0) {
+ if (!smooth_caps) {
+ w_before *= -before / (float)i;
}
+ before = 0;
}
- else {
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
+ if (after > gps->totpoints - 1) {
+ if (!smooth_caps) {
+ w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - i);
+ }
+ after = gps->totpoints - 1;
}
+ }
- pt1 = &gps->points[before];
- pt2 = &gps->points[after];
+ /* Add both these points in relative coordinates to the weighted average sum. */
+ sub_v3_v3v3(tmp, &gps->points[before].x, &pt->x);
+ madd_v3_v3fl(sco, tmp, w_before);
+ sub_v3_v3v3(tmp, &gps->points[after].x, &pt->x);
+ madd_v3_v3fl(sco, tmp, w_after);
- /* add both these points to the average-sum (s += p[i]/n) */
- madd_v3_v3fl(sco, &pt1->x, average_fac);
- madd_v3_v3fl(sco, &pt2->x, average_fac);
- }
+ total_w += w_before;
+ total_w += w_after;
+
+ w *= (n_half + step) / (double)(n_half + 1 - step);
+ w2 *= (n_half * 3 + step) / (double)(n_half * 3 + 1 - step);
}
+ total_w += w - w2;
+ /* The accumulated weight total_w should be
+ * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100
+ * here, but sometimes not quite. */
+ mul_v3_fl(sco, (float)(1.0 / total_w));
+ /* Shift back to global coordinates. */
+ add_v3_v3(sco, &pt->x);
- /* Based on influence factor, blend between original and optimal smoothed coordinate */
- interp_v3_v3v3(&pt->x, &pt->x, sco, inf);
+ /* Based on influence factor, blend between original and optimal smoothed coordinate. */
+ interp_v3_v3v3(&r_gps->points[i].x, &pt->x, sco, influence);
return true;
}
@@ -1058,74 +1100,54 @@ bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf, const bo
/** \name Stroke Smooth Strength
* \{ */
-bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float influence)
+bool BKE_gpencil_stroke_smooth_strength(
+ bGPDstroke *gps, int i, float influence, int iterations, bGPDstroke *r_gps)
{
- bGPDspoint *ptb = &gps->points[point_index];
- const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
-
- /* Do nothing if not enough points */
- if ((gps->totpoints <= 2) || (point_index < 1)) {
+ /* If nothing to do, return early */
+ if (gps->totpoints <= 2 || iterations <= 0) {
return false;
}
- /* Only affect endpoints by a fraction of the normal influence */
- float inf = influence;
- if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) {
- inf *= 0.01f;
- }
- /* Limit max influence to reduce pop effect. */
- CLAMP_MAX(inf, 0.98f);
-
- float total = 0.0f;
- float max_strength = 0.0f;
- const int steps = 4;
- const float average_fac = 1.0f / (float)(steps * 2 + 1);
- int step;
- /* add the point itself */
- total += ptb->strength * average_fac;
- max_strength = ptb->strength;
+ /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */
- /* n-steps before/after current point */
- for (step = 1; step <= steps; step++) {
- bGPDspoint *pt1, *pt2;
- int before = point_index - step;
- int after = point_index + step;
+ const bGPDspoint *pt = &gps->points[i];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
+ float strength = 0.0f;
+ const int n_half = (iterations * iterations) / 4 + iterations;
+ double w = 1.0;
+ double total_w = 0.0;
+ for (int step = iterations; step > 0; step--) {
+ int before = i - step;
+ int after = i + step;
+ float w_before = (float)w;
+ float w_after = (float)w;
if (is_cyclic) {
- if (before < 0) {
- /* Sub to end point (before is already negative). */
- before = gps->totpoints + before;
- CLAMP(before, 0, gps->totpoints - 1);
- }
- if (after > gps->totpoints - 1) {
- /* Add to start point. */
- after = after - gps->totpoints;
- CLAMP(after, 0, gps->totpoints - 1);
- }
+ before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
+ after = after % gps->totpoints;
}
else {
CLAMP_MIN(before, 0);
CLAMP_MAX(after, gps->totpoints - 1);
}
- pt1 = &gps->points[before];
- pt2 = &gps->points[after];
- /* add both these points to the average-sum (s += p[i]/n) */
- total += pt1->strength * average_fac;
- total += pt2->strength * average_fac;
- /* Save max value. */
- if (max_strength < pt1->strength) {
- max_strength = pt1->strength;
- }
- if (max_strength < pt2->strength) {
- max_strength = pt2->strength;
- }
+ /* Add both these points in relative coordinates to the weighted average sum. */
+ strength += w_before * (gps->points[before].strength - pt->strength);
+ strength += w_after * (gps->points[after].strength - pt->strength);
+
+ total_w += w_before;
+ total_w += w_after;
+
+ w *= (n_half + step) / (double)(n_half + 1 - step);
}
+ total_w += w;
+ /* The accumulated weight total_w should be
+ * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100
+ * here, but sometimes not quite. */
+ strength /= total_w;
/* Based on influence factor, blend between original and optimal smoothed value. */
- ptb->strength = interpf(ptb->strength, total, inf);
- /* Clamp to maximum stroke strength to avoid weird results. */
- CLAMP_MAX(ptb->strength, max_strength);
+ r_gps->points[i].strength = pt->strength + strength * influence;
return true;
}
@@ -1136,74 +1158,55 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float
/** \name Stroke Smooth Thickness
* \{ */
-bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float influence)
+bool BKE_gpencil_stroke_smooth_thickness(
+ bGPDstroke *gps, int i, float influence, int iterations, bGPDstroke *r_gps)
{
- bGPDspoint *ptb = &gps->points[point_index];
- const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
-
- /* Do nothing if not enough points */
- if ((gps->totpoints <= 2) || (point_index < 1)) {
+ /* If nothing to do, return early */
+ if (gps->totpoints <= 2 || iterations <= 0) {
return false;
}
- /* Only affect endpoints by a fraction of the normal influence */
- float inf = influence;
- if (!is_cyclic && ELEM(point_index, 0, gps->totpoints - 1)) {
- inf *= 0.01f;
- }
- /* Limit max influence to reduce pop effect. */
- CLAMP_MAX(inf, 0.98f);
-
- float total = 0.0f;
- float max_pressure = 0.0f;
- const int steps = 4;
- const float average_fac = 1.0f / (float)(steps * 2 + 1);
- int step;
- /* add the point itself */
- total += ptb->pressure * average_fac;
- max_pressure = ptb->pressure;
+ /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */
- /* n-steps before/after current point */
- for (step = 1; step <= steps; step++) {
- bGPDspoint *pt1, *pt2;
- int before = point_index - step;
- int after = point_index + step;
+ const bGPDspoint *pt = &gps->points[i];
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
+ float pressure = 0.0f;
+ const int n_half = (iterations * iterations) / 4 + iterations;
+ double w = 1.0;
+ double total_w = 0.0;
+ for (int step = iterations; step > 0; step--) {
+ int before = i - step;
+ int after = i + step;
+ float w_before = (float)w;
+ float w_after = (float)w;
if (is_cyclic) {
- if (before < 0) {
- /* Sub to end point (before is already negative). */
- before = gps->totpoints + before;
- CLAMP(before, 0, gps->totpoints - 1);
- }
- if (after > gps->totpoints - 1) {
- /* Add to start point. */
- after = after - gps->totpoints;
- CLAMP(after, 0, gps->totpoints - 1);
- }
+ before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
+ after = after % gps->totpoints;
}
else {
CLAMP_MIN(before, 0);
CLAMP_MAX(after, gps->totpoints - 1);
}
- pt1 = &gps->points[before];
- pt2 = &gps->points[after];
- /* add both these points to the average-sum (s += p[i]/n) */
- total += pt1->pressure * average_fac;
- total += pt2->pressure * average_fac;
- /* Save max value. */
- if (max_pressure < pt1->pressure) {
- max_pressure = pt1->pressure;
- }
- if (max_pressure < pt2->pressure) {
- max_pressure = pt2->pressure;
- }
+ /* Add both these points in relative coordinates to the weighted average sum. */
+ pressure += w_before * (gps->points[before].pressure - pt->pressure);
+ pressure += w_after * (gps->points[after].pressure - pt->pressure);
+
+ total_w += w_before;
+ total_w += w_after;
+
+ w *= (n_half + step) / (double)(n_half + 1 - step);
}
+ total_w += w;
+ /* The accumulated weight total_w should be
+ * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100
+ * here, but sometimes not quite. */
+ pressure /= total_w;
/* Based on influence factor, blend between original and optimal smoothed value. */
- ptb->pressure = interpf(ptb->pressure, total, inf);
- /* Clamp to maximum stroke thickness to avoid weird results. */
- CLAMP_MAX(ptb->pressure, max_pressure);
+ r_gps->points[i].pressure = pt->pressure + pressure * influence;
+
return true;
}
@@ -1213,57 +1216,127 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float
/** \name Stroke Smooth UV
* \{ */
-bool BKE_gpencil_stroke_smooth_uv(bGPDstroke *gps, int point_index, float influence)
+bool BKE_gpencil_stroke_smooth_uv(
+ struct bGPDstroke *gps, int i, float influence, int iterations, struct bGPDstroke *r_gps)
{
- bGPDspoint *ptb = &gps->points[point_index];
+ /* If nothing to do, return early */
+ if (gps->totpoints <= 2 || iterations <= 0) {
+ return false;
+ }
+
+ /* See BKE_gpencil_stroke_smooth_point for details on the algorithm. */
+
+ const bGPDspoint *pt = &gps->points[i];
const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
- /* Do nothing if not enough points */
- if (gps->totpoints <= 2) {
- return false;
+ /* If don't change the caps. */
+ if (!is_cyclic && ELEM(i, 0, gps->totpoints - 1)) {
+ r_gps->points[i].uv_rot = pt->uv_rot;
+ r_gps->points[i].uv_fac = pt->uv_fac;
+ return true;
}
- /* Compute theoretical optimal value */
- bGPDspoint *pta, *ptc;
- int before = point_index - 1;
- int after = point_index + 1;
+ float uv_rot = 0.0f;
+ float uv_fac = 0.0f;
+ const int n_half = iterations * iterations + iterations;
+ double w = 1.0;
+ double total_w = 0.0;
+ for (int step = iterations; step > 0; step--) {
+ int before = i - step;
+ int after = i + step;
+ float w_before = (float)w;
+ float w_after = (float)w;
- if (is_cyclic) {
- if (before < 0) {
- /* Sub to end point (before is already negative). */
- before = gps->totpoints + before;
- CLAMP(before, 0, gps->totpoints - 1);
+ if (is_cyclic) {
+ before = (before % gps->totpoints + gps->totpoints) % gps->totpoints;
+ after = after % gps->totpoints;
}
- if (after > gps->totpoints - 1) {
- /* Add to start point. */
- after = after - gps->totpoints;
- CLAMP(after, 0, gps->totpoints - 1);
+ else {
+ if (before < 0) {
+ w_before *= -before / (float)i;
+ before = 0;
+ }
+ if (after > gps->totpoints - 1) {
+ w_after *= (after - (gps->totpoints - 1)) / (float)(gps->totpoints - 1 - i);
+ after = gps->totpoints - 1;
+ }
}
- }
- else {
- CLAMP_MIN(before, 0);
- CLAMP_MAX(after, gps->totpoints - 1);
- }
- pta = &gps->points[before];
- ptc = &gps->points[after];
- /* the optimal value is the corresponding to the interpolation of the pressure
- * at the distance of point b
- */
- float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
- /* sometimes the factor can be wrong due stroke geometry, so use middle point */
- if ((fac < 0.0f) || (fac > 1.0f)) {
- fac = 0.5f;
+ /* Add both these points in relative coordinates to the weighted average sum. */
+ uv_rot += w_before * (gps->points[before].uv_rot - pt->uv_rot);
+ uv_rot += w_after * (gps->points[after].uv_rot - pt->uv_rot);
+ uv_fac += w_before * (gps->points[before].uv_fac - pt->uv_fac);
+ uv_fac += w_after * (gps->points[after].uv_fac - pt->uv_fac);
+
+ total_w += w_before;
+ total_w += w_after;
+
+ w *= (n_half + step) / (double)(n_half + 1 - step);
}
- float optimal = interpf(ptc->uv_rot, pta->uv_rot, fac);
+ total_w += w;
+ /* The accumulated weight total_w should be
+ * ~sqrt(M_PI * n_half) * exp((iterations * iterations) / n_half) < 100
+ * here, but sometimes not quite. */
+ uv_rot /= total_w;
+ uv_fac /= total_w;
- /* Based on influence factor, blend between original and optimal */
- ptb->uv_rot = interpf(optimal, ptb->uv_rot, influence);
- CLAMP(ptb->uv_rot, -M_PI_2, M_PI_2);
+ /* Based on influence factor, blend between original and optimal smoothed value. */
+ r_gps->points[i].uv_rot = pt->uv_rot + uv_rot * influence;
+ r_gps->points[i].uv_fac = pt->uv_fac + uv_fac * influence;
return true;
}
+void BKE_gpencil_stroke_smooth(bGPDstroke *gps,
+ const float influence,
+ const int iterations,
+ const bool smooth_position,
+ const bool smooth_strength,
+ const bool smooth_thickness,
+ const bool smooth_uv,
+ const bool keep_shape,
+ const float *weights)
+{
+ if (influence <= 0 || iterations <= 0) {
+ return;
+ }
+
+ /* Make a copy of the point data to avoid directionality of the smooth operation. */
+ bGPDstroke gps_old = *gps;
+ gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points);
+
+ /* Smooth stroke. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ float val = influence;
+ if (weights != NULL) {
+ val *= weights[i];
+ if (val <= 0.0f) {
+ continue;
+ }
+ }
+
+ /* TODO: Currently the weights only control the influence, but is would be much better if they
+ * would control the distribution used in smooth, similar to how the ends are handled. */
+
+ /* Perform smoothing. */
+ if (smooth_position) {
+ BKE_gpencil_stroke_smooth_point(&gps_old, i, val, iterations, false, keep_shape, gps);
+ }
+ if (smooth_strength) {
+ BKE_gpencil_stroke_smooth_strength(&gps_old, i, val, iterations, gps);
+ }
+ if (smooth_thickness) {
+ BKE_gpencil_stroke_smooth_thickness(&gps_old, i, val, iterations, gps);
+ }
+ if (smooth_uv) {
+ BKE_gpencil_stroke_smooth_uv(&gps_old, i, val, iterations, gps);
+ }
+ }
+
+ /* Free the copied points array. */
+ MEM_freeN(gps_old.points);
+}
+
void BKE_gpencil_stroke_2d_flat(const bGPDspoint *points,
int totpoints,
float (*points2d)[2],
@@ -3443,7 +3516,7 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
for (i = start; i < end; i++) {
pt = &gps_a->points[i];
pt->pressure += (avg_pressure - pt->pressure) * ratio;
- BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f, false);
+ BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f, 2, false, true, gps_a);
ratio += step;
/* In the center, reverse the ratio. */
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc
index cfdd048495d..3eade265bf2 100644
--- a/source/blender/blenkernel/intern/image.cc
+++ b/source/blender/blenkernel/intern/image.cc
@@ -9,6 +9,7 @@
#include <cmath>
#include <cstdio>
#include <cstring>
+#include <ctime>
#include <fcntl.h>
#ifndef WIN32
# include <unistd.h>
@@ -16,7 +17,8 @@
# include <io.h>
#endif
-#include <ctime>
+#include <regex>
+#include <string>
#include "BLI_array.hh"
@@ -237,7 +239,7 @@ static void image_foreach_cache(ID *id,
auto gputexture_offset = [image](int target, int eye, int resolution) {
constexpr size_t base_offset = offsetof(Image, gputexture);
- const auto first = &image->gputexture[0][0][0];
+ struct GPUTexture **first = &image->gputexture[0][0][0];
const size_t array_offset = sizeof(*first) *
(&image->gputexture[target][eye][resolution] - first);
return base_offset + array_offset;
@@ -466,7 +468,9 @@ constexpr IDTypeInfo get_type_info()
IDTypeInfo IDType_ID_IM = get_type_info();
/* prototypes */
-static int image_num_files(struct Image *ima);
+static int image_num_viewfiles(Image *ima);
+static ImBuf *image_load_image_file(
+ Image *ima, ImageUser *iuser, int entry, int cfra, bool is_sequence);
static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock);
static void image_update_views_format(Image *ima, ImageUser *iuser);
static void image_add_view(Image *ima, const char *viewname, const char *filepath);
@@ -487,9 +491,9 @@ static void image_add_view(Image *ima, const char *viewname, const char *filepat
/** \name Image Cache
* \{ */
-typedef struct ImageCacheKey {
+struct ImageCacheKey {
int index;
-} ImageCacheKey;
+};
static unsigned int imagecache_hashhash(const void *key_v)
{
@@ -1275,9 +1279,9 @@ bool BKE_image_memorypack(Image *ima)
void BKE_image_packfiles(ReportList *reports, Image *ima, const char *basepath)
{
- const int totfiles = image_num_files(ima);
+ const int tot_viewfiles = image_num_viewfiles(ima);
- if (totfiles == 1) {
+ if (tot_viewfiles == 1) {
ImagePackedFile *imapf = static_cast<ImagePackedFile *>(
MEM_mallocN(sizeof(ImagePackedFile), "Image packed file"));
BLI_addtail(&ima->packedfiles, imapf);
@@ -1311,9 +1315,9 @@ void BKE_image_packfiles_from_mem(ReportList *reports,
char *data,
const size_t data_len)
{
- const int totfiles = image_num_files(ima);
+ const int tot_viewfiles = image_num_viewfiles(ima);
- if (totfiles != 1) {
+ if (tot_viewfiles != 1) {
BKE_report(reports, RPT_ERROR, "Cannot pack multiview images from raw data currently...");
}
else {
@@ -2942,9 +2946,9 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal)
case IMA_SIGNAL_RELOAD:
/* try to repack file */
if (BKE_image_has_packedfile(ima)) {
- const int totfiles = image_num_files(ima);
+ const int tot_viewfiles = image_num_viewfiles(ima);
- if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) {
+ if (tot_viewfiles != BLI_listbase_count_at_most(&ima->packedfiles, tot_viewfiles + 1)) {
/* in case there are new available files to be loaded */
image_free_packedfiles(ima);
BKE_image_packfiles(nullptr, ima, ID_BLEND_PATH(bmain, &ima->id));
@@ -3111,14 +3115,15 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *tile_start, i
int max_udim = 0;
int id;
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(dirname, &dir);
- for (int i = 0; i < totfile; i++) {
- if (!(dir[i].type & S_IFREG)) {
+ struct direntry *dirs;
+ const uint dirs_num = BLI_filelist_dir_contents(dirname, &dirs);
+ for (int i = 0; i < dirs_num; i++) {
+ if (!(dirs[i].type & S_IFREG)) {
continue;
}
- if (!BKE_image_get_tile_number_from_filepath(dir[i].relname, udim_pattern, tile_format, &id)) {
+ if (!BKE_image_get_tile_number_from_filepath(
+ dirs[i].relname, udim_pattern, tile_format, &id)) {
continue;
}
@@ -3131,7 +3136,7 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *tile_start, i
min_udim = min_ii(min_udim, id);
max_udim = max_ii(max_udim, id);
}
- BLI_filelist_free(dir, totfile);
+ BLI_filelist_free(dirs, dirs_num);
MEM_SAFE_FREE(udim_pattern);
if (is_udim && min_udim <= IMA_UDIM_MAX) {
@@ -3316,69 +3321,24 @@ void BKE_image_ensure_tile_token(char *filename)
return;
}
- /* Is there a sequence of digits in the filename? */
- ushort digits;
- char head[FILE_MAX], tail[FILE_MAX];
- BLI_path_sequence_decode(filename, head, tail, &digits);
- if (digits == 4) {
- sprintf(filename, "%s<UDIM>%s", head, tail);
- return;
- }
-
- /* Is there a sequence like u##_v#### in the filename? */
- uint cur = 0;
- uint name_end = strlen(filename);
- uint u_digits = 0;
- uint v_digits = 0;
- uint u_start = (uint)-1;
- bool u_found = false;
- bool v_found = false;
- bool sep_found = false;
- while (cur < name_end) {
- if (filename[cur] == 'u') {
- u_found = true;
- u_digits = 0;
- u_start = cur;
- }
- else if (filename[cur] == 'v') {
- v_found = true;
- v_digits = 0;
- }
- else if (u_found && !v_found) {
- if (isdigit(filename[cur]) && u_digits < 2) {
- u_digits++;
- }
- else if (filename[cur] == '_') {
- sep_found = true;
- }
- else {
- u_found = false;
- }
- }
- else if (u_found && u_digits > 0 && v_found) {
- if (isdigit(filename[cur])) {
- if (v_digits < 4) {
- v_digits++;
- }
- else {
- u_found = false;
- v_found = false;
- }
- }
- else if (v_digits > 0) {
- break;
- }
- }
+ std::string path(filename);
+ std::smatch match;
- cur++;
+ /* General 4-digit "udim" pattern. As this format is susceptible to ambiguity
+ * with other digit sequences, we can leverage the supported range of roughly
+ * 1000 through 2000 to provide better detection.
+ */
+ std::regex pattern(R"((^|.*?\D)([12]\d{3})(\D.*))");
+ if (std::regex_search(path, match, pattern)) {
+ BLI_strncpy(filename, match.format("$1<UDIM>$3").c_str(), FILE_MAX);
+ return;
}
- if (u_found && sep_found && v_found && (u_digits + v_digits > 1)) {
- const char *token = "<UVTILE>";
- const size_t token_length = strlen(token);
- memmove(filename + u_start + token_length, filename + cur, name_end - cur);
- memcpy(filename + u_start, token, token_length);
- filename[u_start + token_length + (name_end - cur)] = '\0';
+ /* General `u##_v###` `uvtile` pattern. */
+ pattern = std::regex(R"((.*)(u\d{1,2}_v\d{1,3})(\D.*))");
+ if (std::regex_search(path, match, pattern)) {
+ BLI_strncpy(filename, match.format("$1<UVTILE>$3").c_str(), FILE_MAX);
+ return;
}
}
@@ -3393,15 +3353,15 @@ bool BKE_image_tile_filepath_exists(const char *filepath)
char *udim_pattern = BKE_image_get_tile_strformat(filepath, &tile_format);
bool found = false;
- struct direntry *dir;
- uint totfile = BLI_filelist_dir_contents(dirname, &dir);
- for (int i = 0; i < totfile; i++) {
- if (!(dir[i].type & S_IFREG)) {
+ struct direntry *dirs;
+ const uint dirs_num = BLI_filelist_dir_contents(dirname, &dirs);
+ for (int i = 0; i < dirs_num; i++) {
+ if (!(dirs[i].type & S_IFREG)) {
continue;
}
int id;
- if (!BKE_image_get_tile_number_from_filepath(dir[i].path, udim_pattern, tile_format, &id)) {
+ if (!BKE_image_get_tile_number_from_filepath(dirs[i].path, udim_pattern, tile_format, &id)) {
continue;
}
@@ -3412,7 +3372,7 @@ bool BKE_image_tile_filepath_exists(const char *filepath)
found = true;
break;
}
- BLI_filelist_free(dir, totfile);
+ BLI_filelist_free(dirs, dirs_num);
MEM_SAFE_FREE(udim_pattern);
return found;
@@ -3781,7 +3741,7 @@ static int imbuf_alpha_flags_for_image(Image *ima)
/**
* \return the number of files will vary according to the stereo format.
*/
-static int image_num_files(Image *ima)
+static int image_num_viewfiles(Image *ima)
{
const bool is_multiview = BKE_image_is_multiview(ima);
@@ -3796,117 +3756,6 @@ static int image_num_files(Image *ima)
return BLI_listbase_count(&ima->views);
}
-static ImBuf *load_sequence_single(
- Image *ima, ImageUser *iuser, int frame, const int view_id, bool *r_cache_ibuf)
-{
- struct ImBuf *ibuf;
- char name[FILE_MAX];
- int flag;
- ImageUser iuser_t{};
-
- *r_cache_ibuf = true;
-
- ima->lastframe = frame;
-
- if (iuser) {
- iuser_t = *iuser;
- }
- else {
- /* BKE_image_user_file_path() uses this value for file name for sequences. */
- iuser_t.framenr = frame;
- /* TODO(sergey): Do we need to initialize something else here? */
- }
-
- iuser_t.view = view_id;
- BKE_image_user_file_path(&iuser_t, ima, name);
-
- flag = IB_rect | IB_multilayer | IB_metadata;
- flag |= imbuf_alpha_flags_for_image(ima);
-
- /* read ibuf */
- ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
-
-#if 0
- if (ibuf) {
- printf(AT " loaded %s\n", name);
- }
- else {
- printf(AT " missed %s\n", name);
- }
-#endif
-
- if (ibuf) {
-#ifdef WITH_OPENEXR
- if (ibuf->ftype == IMB_FTYPE_OPENEXR && ibuf->userdata) {
- /* Handle multilayer and multiview cases, don't assign ibuf here.
- * will be set layer in BKE_image_acquire_ibuf from ima->rr. */
- if (IMB_exr_has_multilayer(ibuf->userdata)) {
- image_create_multilayer(ima, ibuf, frame);
- ima->type = IMA_TYPE_MULTILAYER;
- IMB_freeImBuf(ibuf);
- ibuf = nullptr;
- /* Null ibuf in the cache means the image failed to load. However for multilayer we load
- * pixels into RenderResult instead and intentionally leave ibuf null. */
- *r_cache_ibuf = false;
- }
- }
- else {
- image_init_after_load(ima, iuser, ibuf);
- }
-#else
- image_init_after_load(ima, iuser, ibuf);
-#endif
- }
-
- return ibuf;
-}
-
-static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int entry, int frame)
-{
- struct ImBuf *ibuf = nullptr;
- const bool is_multiview = BKE_image_is_multiview(ima);
- const int totfiles = image_num_files(ima);
-
- if (!is_multiview) {
- bool put_in_cache;
- ibuf = load_sequence_single(ima, iuser, frame, 0, &put_in_cache);
- if (put_in_cache) {
- image_assign_ibuf(ima, ibuf, 0, entry);
- }
- }
- else {
- const int totviews = BLI_listbase_count(&ima->views);
- Array<ImBuf *> ibuf_arr(totviews);
- Array<bool> cache_ibuf_arr(totviews);
-
- for (int i = 0; i < totfiles; i++) {
- ibuf_arr[i] = load_sequence_single(ima, iuser, frame, i, &cache_ibuf_arr[i]);
- }
-
- if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) {
- IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
- }
-
- /* return the original requested ImBuf */
- ibuf = ibuf_arr[(iuser ? iuser->multi_index : 0)];
-
- for (int i = 0; i < totviews; i++) {
- if (cache_ibuf_arr[i]) {
- image_assign_ibuf(ima, ibuf_arr[i], i, entry);
- }
- }
-
- /* "remove" the others (decrease their refcount) */
- for (int i = 0; i < totviews; i++) {
- if (ibuf_arr[i] != ibuf) {
- IMB_freeImBuf(ibuf_arr[i]);
- }
- }
- }
-
- return ibuf;
-}
-
static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int entry, int frame)
{
struct ImBuf *ibuf = nullptr;
@@ -3925,7 +3774,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e
ima->rr = nullptr;
}
- ibuf = image_load_sequence_file(ima, iuser, entry, frame);
+ ibuf = image_load_image_file(ima, iuser, entry, frame, true);
if (ibuf) { /* actually an error */
ima->type = IMA_TYPE_IMAGE;
@@ -4012,12 +3861,12 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
{
struct ImBuf *ibuf = nullptr;
const bool is_multiview = BKE_image_is_multiview(ima);
- const int totfiles = image_num_files(ima);
+ const int tot_viewfiles = image_num_viewfiles(ima);
- if (totfiles != BLI_listbase_count_at_most(&ima->anims, totfiles + 1)) {
+ if (tot_viewfiles != BLI_listbase_count_at_most(&ima->anims, tot_viewfiles + 1)) {
image_free_anims(ima);
- for (int i = 0; i < totfiles; i++) {
+ for (int i = 0; i < tot_viewfiles; i++) {
/* allocate the ImageAnim */
ImageAnim *ia = MEM_cnew<ImageAnim>("Image Anim");
BLI_addtail(&ima->anims, ia);
@@ -4032,7 +3881,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
const int totviews = BLI_listbase_count(&ima->views);
Array<ImBuf *> ibuf_arr(totviews);
- for (int i = 0; i < totfiles; i++) {
+ for (int i = 0; i < tot_viewfiles; i++) {
ibuf_arr[i] = load_movie_single(ima, iuser, frame, i);
}
@@ -4063,23 +3912,21 @@ static ImBuf *load_image_single(Image *ima,
int cfra,
const int view_id,
const bool has_packed,
+ const bool is_sequence,
bool *r_cache_ibuf)
{
char filepath[FILE_MAX];
struct ImBuf *ibuf = nullptr;
- int flag;
+ int flag = IB_rect | IB_multilayer;
*r_cache_ibuf = true;
/* is there a PackedFile with this image ? */
- if (has_packed) {
- ImagePackedFile *imapf;
-
- flag = IB_rect | IB_multilayer;
- flag |= imbuf_alpha_flags_for_image(ima);
-
- imapf = static_cast<ImagePackedFile *>(BLI_findlink(&ima->packedfiles, view_id));
+ if (has_packed && !is_sequence) {
+ ImagePackedFile *imapf = static_cast<ImagePackedFile *>(
+ BLI_findlink(&ima->packedfiles, view_id));
if (imapf->packedfile) {
+ flag |= imbuf_alpha_flags_for_image(ima);
ibuf = IMB_ibImageFromMemory((unsigned char *)imapf->packedfile->data,
imapf->packedfile->size,
flag,
@@ -4088,14 +3935,17 @@ static ImBuf *load_image_single(Image *ima,
}
}
else {
- ImageUser iuser_t{};
-
- flag = IB_rect | IB_multilayer | IB_metadata;
- flag |= imbuf_alpha_flags_for_image(ima);
+ if (is_sequence) {
+ ima->lastframe = cfra;
+ }
/* get the correct filepath */
- BKE_image_user_frame_calc(ima, iuser, cfra);
+ const bool is_tiled = (ima->source == IMA_SRC_TILED);
+ if (!(is_sequence || is_tiled)) {
+ BKE_image_user_frame_calc(ima, iuser, cfra);
+ }
+ ImageUser iuser_t{};
if (iuser) {
iuser_t = *iuser;
}
@@ -4108,6 +3958,8 @@ static ImBuf *load_image_single(Image *ima,
BKE_image_user_file_path(&iuser_t, ima, filepath);
/* read ibuf */
+ flag |= IB_metadata;
+ flag |= imbuf_alpha_flags_for_image(ima);
ibuf = IMB_loadiffname(filepath, flag, ima->colorspace_settings.name);
}
@@ -4132,7 +3984,7 @@ static ImBuf *load_image_single(Image *ima,
image_init_after_load(ima, iuser, ibuf);
/* Make packed file for auto-pack. */
- if ((has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) {
+ if (!is_sequence && (has_packed == false) && (G.fileflags & G_FILE_AUTOPACK)) {
ImagePackedFile *imapf = static_cast<ImagePackedFile *>(
MEM_mallocN(sizeof(ImagePackedFile), "Image Pack-file"));
BLI_addtail(&ima->packedfiles, imapf);
@@ -4150,18 +4002,23 @@ static ImBuf *load_image_single(Image *ima,
/* warning, 'iuser' can be null
* NOTE: Image->views was already populated (in image_update_views_format)
*/
-static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
+static ImBuf *image_load_image_file(
+ Image *ima, ImageUser *iuser, int entry, int cfra, bool is_sequence)
{
struct ImBuf *ibuf = nullptr;
const bool is_multiview = BKE_image_is_multiview(ima);
- const int totfiles = image_num_files(ima);
+ const bool is_tiled = (ima->source == IMA_SRC_TILED);
+ const int tot_viewfiles = image_num_viewfiles(ima);
bool has_packed = BKE_image_has_packedfile(ima);
- /* always ensure clean ima */
- BKE_image_free_buffers(ima);
+ if (!(is_sequence || is_tiled)) {
+ /* ensure clean ima */
+ BKE_image_free_buffers(ima);
+ }
/* this should never happen, but just playing safe */
- if (has_packed) {
+ if (!is_sequence && has_packed) {
+ const int totfiles = tot_viewfiles * BLI_listbase_count(&ima->tiles);
if (totfiles != BLI_listbase_count_at_most(&ima->packedfiles, totfiles + 1)) {
image_free_packedfiles(ima);
has_packed = false;
@@ -4170,9 +4027,10 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
if (!is_multiview) {
bool put_in_cache;
- ibuf = load_image_single(ima, iuser, cfra, 0, has_packed, &put_in_cache);
+ ibuf = load_image_single(ima, iuser, cfra, 0, has_packed, is_sequence, &put_in_cache);
if (put_in_cache) {
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ const int index = (is_sequence || is_tiled) ? 0 : IMA_NO_INDEX;
+ image_assign_ibuf(ima, ibuf, index, entry);
}
}
else {
@@ -4182,28 +4040,29 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
Array<ImBuf *> ibuf_arr(totviews);
Array<bool> cache_ibuf_arr(totviews);
- for (int i = 0; i < totfiles; i++) {
- ibuf_arr[i] = load_image_single(ima, iuser, cfra, i, has_packed, &cache_ibuf_arr[i]);
+ for (int i = 0; i < tot_viewfiles; i++) {
+ ibuf_arr[i] = load_image_single(
+ ima, iuser, cfra, i, has_packed, is_sequence, &cache_ibuf_arr[i]);
}
/* multi-views/multi-layers OpenEXR files directly populate ima, and return null ibuf... */
if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D && ibuf_arr[0] &&
- totfiles == 1 && totviews >= 2) {
+ tot_viewfiles == 1 && totviews >= 2) {
IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]);
}
/* return the original requested ImBuf */
- int i = (iuser && iuser->multi_index < totviews) ? iuser->multi_index : 0;
- ibuf = ibuf_arr[i];
+ const int ibuf_index = (iuser && iuser->multi_index < totviews) ? iuser->multi_index : 0;
+ ibuf = ibuf_arr[ibuf_index];
- for (i = 0; i < totviews; i++) {
+ for (int i = 0; i < totviews; i++) {
if (cache_ibuf_arr[i]) {
- image_assign_ibuf(ima, ibuf_arr[i], i, 0);
+ image_assign_ibuf(ima, ibuf_arr[i], i, entry);
}
}
/* "remove" the others (decrease their refcount) */
- for (i = 0; i < totviews; i++) {
+ for (int i = 0; i < totviews; i++) {
if (ibuf_arr[i] != ibuf) {
IMB_freeImBuf(ibuf_arr[i]);
}
@@ -4218,7 +4077,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
ImBuf *ibuf = nullptr;
if (ima->rr == nullptr) {
- ibuf = image_load_image_file(ima, iuser, 0);
+ ibuf = image_load_image_file(ima, iuser, 0, 0, false);
if (ibuf) { /* actually an error */
ima->type = IMA_TYPE_IMAGE;
return ibuf;
@@ -4595,7 +4454,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
else if (ima->source == IMA_SRC_SEQUENCE) {
if (ima->type == IMA_TYPE_IMAGE) {
/* Regular files, ibufs in flip-book, allows saving. */
- ibuf = image_load_sequence_file(ima, iuser, entry, entry);
+ ibuf = image_load_image_file(ima, iuser, entry, entry, true);
}
/* no else; on load the ima type can change */
if (ima->type == IMA_TYPE_MULTILAYER) {
@@ -4606,7 +4465,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
else if (ima->source == IMA_SRC_TILED) {
if (ima->type == IMA_TYPE_IMAGE) {
/* Regular files, ibufs in flip-book, allows saving */
- ibuf = image_load_sequence_file(ima, iuser, entry, 0);
+ ibuf = image_load_image_file(ima, iuser, entry, 0, false);
}
/* no else; on load the ima type can change */
if (ima->type == IMA_TYPE_MULTILAYER) {
@@ -4617,7 +4476,8 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
else if (ima->source == IMA_SRC_FILE) {
if (ima->type == IMA_TYPE_IMAGE) {
- ibuf = image_load_image_file(ima, iuser, entry); /* cfra only for '#', this global is OK */
+ ibuf = image_load_image_file(
+ ima, iuser, 0, entry, false); /* cfra only for '#', this global is OK */
}
/* no else; on load the ima type can change */
if (ima->type == IMA_TYPE_MULTILAYER) {
@@ -5096,7 +4956,7 @@ void BKE_image_user_file_path_ex(ImageUser *iuser, Image *ima, char *filepath, b
bool BKE_image_has_alpha(Image *image)
{
void *lock;
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(image, nullptr, &lock);
const int planes = (ibuf ? ibuf->planes : 0);
BKE_image_release_ibuf(image, ibuf, lock);
diff --git a/source/blender/blenkernel/intern/image_format.cc b/source/blender/blenkernel/intern/image_format.cc
index 44aa9e21195..3ff0b3da963 100644
--- a/source/blender/blenkernel/intern/image_format.cc
+++ b/source/blender/blenkernel/intern/image_format.cc
@@ -5,7 +5,7 @@
* \ingroup bke
*/
-#include <string.h>
+#include <cstring>
#include "DNA_defaults.h"
#include "DNA_scene_types.h"
@@ -120,6 +120,12 @@ int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
return IMB_FTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (imtype == R_IMF_IMTYPE_WEBP) {
+ r_options->quality = 90;
+ return IMB_FTYPE_WEBP;
+ }
+#endif
r_options->quality = 90;
return IMB_FTYPE_JPG;
@@ -177,6 +183,11 @@ char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
return R_IMF_IMTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (ftype == IMB_FTYPE_WEBP) {
+ return R_IMF_IMTYPE_WEBP;
+ }
+#endif
return R_IMF_IMTYPE_JPEG90;
}
@@ -220,6 +231,7 @@ bool BKE_imtype_supports_quality(const char imtype)
case R_IMF_IMTYPE_JPEG90:
case R_IMF_IMTYPE_JP2:
case R_IMF_IMTYPE_AVIJPEG:
+ case R_IMF_IMTYPE_WEBP:
return true;
}
return false;
@@ -259,6 +271,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file)
case R_IMF_IMTYPE_DDS:
case R_IMF_IMTYPE_JP2:
case R_IMF_IMTYPE_DPX:
+ case R_IMF_IMTYPE_WEBP:
chan_flag |= IMA_CHAN_FLAG_ALPHA;
break;
}
@@ -379,6 +392,11 @@ char BKE_imtype_from_arg(const char *imtype_arg)
return R_IMF_IMTYPE_JP2;
}
#endif
+#ifdef WITH_WEBP
+ if (STREQ(imtype_arg, "WEBP")) {
+ return R_IMF_IMTYPE_WEBP;
+ }
+#endif
return R_IMF_IMTYPE_INVALID;
}
@@ -494,6 +512,12 @@ static bool do_add_image_extension(char *string,
}
}
#endif
+#ifdef WITH_WEBP
+ else if (imtype == R_IMF_IMTYPE_WEBP) {
+ if (!BLI_path_extension_check(string, extension_test = ".webp"))
+ extension = extension_test;
+ }
+#endif
else { // R_IMF_IMTYPE_AVIRAW, R_IMF_IMTYPE_AVIJPEG, R_IMF_IMTYPE_JPEG90 etc
if (!(BLI_path_extension_check_n(string, extension_test = ".jpg", ".jpeg", nullptr))) {
extension = extension_test;
@@ -732,6 +756,12 @@ void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
}
}
#endif
+#ifdef WITH_WEBP
+ else if (imtype == R_IMF_IMTYPE_WEBP) {
+ ibuf->ftype = IMB_FTYPE_WEBP;
+ ibuf->foptions.quality = quality;
+ }
+#endif
else {
/* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */
if (quality < 10) {
@@ -864,6 +894,12 @@ void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
}
}
#endif
+#ifdef WITH_WEBP
+ else if (ftype == IMB_FTYPE_WEBP) {
+ im_format->imtype = R_IMF_IMTYPE_WEBP;
+ im_format->quality = quality;
+ }
+#endif
else {
im_format->imtype = R_IMF_IMTYPE_JPEG90;
diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc
index 4606a14ab69..c77ee77a5f2 100644
--- a/source/blender/blenkernel/intern/image_partial_update.cc
+++ b/source/blender/blenkernel/intern/image_partial_update.cc
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2021 Blender Foundation. */
/**
- * \file image_gpu_partial_update.cc
+ * \file
* \ingroup bke
*
* To reduce the overhead of image processing this file contains a mechanism to detect areas of the
diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc
index f530183f967..0d7d238f3b2 100644
--- a/source/blender/blenkernel/intern/image_save.cc
+++ b/source/blender/blenkernel/intern/image_save.cc
@@ -391,6 +391,10 @@ static bool image_save_single(ReportList *reports,
}
}
+ if (rr) {
+ BKE_image_release_renderresult(opts->scene, ima);
+ }
+
return ok;
}
@@ -693,7 +697,7 @@ bool BKE_image_render_write(ReportList *reports,
RenderResult *rr,
const Scene *scene,
const bool stamp,
- const char *filename)
+ const char *filepath_basis)
{
bool ok = true;
@@ -711,8 +715,8 @@ bool BKE_image_render_write(ReportList *reports,
const float dither = scene->r.dither_intensity;
if (image_format.views_format == R_IMF_VIEWS_MULTIVIEW && is_exr_rr) {
- ok = BKE_image_render_write_exr(reports, rr, filename, &image_format, true, nullptr, -1);
- image_render_print_save_message(reports, filename, ok, errno);
+ ok = BKE_image_render_write_exr(reports, rr, filepath_basis, &image_format, true, nullptr, -1);
+ image_render_print_save_message(reports, filepath_basis, ok, errno);
}
/* mono, legacy code */
@@ -722,10 +726,10 @@ bool BKE_image_render_write(ReportList *reports,
rv = rv->next, view_id++) {
char filepath[FILE_MAX];
if (is_mono) {
- STRNCPY(filepath, filename);
+ STRNCPY(filepath, filepath_basis);
}
else {
- BKE_scene_multiview_view_filepath_get(&scene->r, filename, rv->name, filepath);
+ BKE_scene_multiview_view_filepath_get(&scene->r, filepath_basis, rv->name, filepath);
}
if (is_exr_rr) {
@@ -768,7 +772,7 @@ bool BKE_image_render_write(ReportList *reports,
BLI_assert(image_format.views_format == R_IMF_VIEWS_STEREO_3D);
char filepath[FILE_MAX];
- STRNCPY(filepath, filename);
+ STRNCPY(filepath, filepath_basis);
if (image_format.imtype == R_IMF_IMTYPE_MULTILAYER) {
printf("Stereo 3D not supported for MultiLayer image: %s\n", filepath);
diff --git a/source/blender/blenkernel/intern/image_test.cc b/source/blender/blenkernel/intern/image_test.cc
new file mode 100644
index 00000000000..9c15fc62d21
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_test.cc
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+
+#include "BKE_image.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "testing/testing.h"
+
+namespace blender::bke::tests {
+
+TEST(udim, image_ensure_tile_token)
+{
+ auto verify = [](const char *original, const char *expected) {
+ char result[FILE_MAX];
+
+ BLI_strncpy(result, original, sizeof(result));
+ BKE_image_ensure_tile_token(result);
+ EXPECT_STREQ(result, expected);
+ };
+
+ /* Already present tokens. */
+ verify("test.<UDIM>.png", "test.<UDIM>.png");
+ verify("test.<UVTILE>.png", "test.<UVTILE>.png");
+
+ /* UDIM pattern detection. */
+ verify("test.1002.png", "test.<UDIM>.png");
+ verify("test-1002-ao.png", "test-<UDIM>-ao.png");
+ verify("test_1002_ao.png", "test_<UDIM>_ao.png");
+ verify("test.1002.ver0023.png", "test.<UDIM>.ver0023.png");
+ verify("test.ver0023.1002.png", "test.ver0023.<UDIM>.png");
+ verify("1002test.png", "<UDIM>test.png");
+ verify("test1002.png", "test<UDIM>.png");
+
+ /* UVTILE pattern detection. */
+ verify("uv-test.u2_v10.png", "uv-test.<UVTILE>.png");
+ verify("uv-test-u2_v10-ao.png", "uv-test-<UVTILE>-ao.png");
+ verify("uv-test_u2_v10_ao.png", "uv-test_<UVTILE>_ao.png");
+ verify("uv-test.u10_v100.png", "uv-test.<UVTILE>.png");
+ verify("u_v-test.u2_v10.png", "u_v-test.<UVTILE>.png");
+ verify("u2_v10uv-test.png", "<UVTILE>uv-test.png");
+ verify("u2_v10u_v-test.png", "<UVTILE>u_v-test.png");
+
+ /* Incorrect patterns. */
+ for (const char *incorrect : {"test.123.png",
+ "test.12345.png",
+ "test.uv.png",
+ "test.u1v.png",
+ "test.uv1.png",
+ "test.u_v.png",
+ "test.u1_v.png",
+ "test.u_v2.png",
+ "test.u2v3.png",
+ "test.u123_v1.png",
+ "test.u1_v12345.png"}) {
+ /* These should not result in modifications happening. */
+ verify(incorrect, incorrect);
+ }
+}
+
+TEST(udim, image_get_tile_strformat)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+
+ /* Parameter validation. */
+ udim_pattern = BKE_image_get_tile_strformat(nullptr, &tile_format);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("", nullptr);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ /* Typical usage. */
+ udim_pattern = BKE_image_get_tile_strformat("", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UNKNOWN>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_NONE);
+ EXPECT_EQ(udim_pattern, nullptr);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_STREQ(udim_pattern, "test.%d.png");
+ MEM_freeN(udim_pattern);
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_STREQ(udim_pattern, "test.u%d_v%d.png");
+ MEM_freeN(udim_pattern);
+}
+
+TEST(udim, image_get_tile_number_from_filepath)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+ int tile_number;
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ /* Parameter validation. */
+ EXPECT_FALSE(
+ BKE_image_get_tile_number_from_filepath(nullptr, udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", nullptr, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, UDIM_TILE_FORMAT_NONE, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, tile_format, nullptr));
+
+ /* UDIM tile format tests. */
+ EXPECT_TRUE(BKE_image_get_tile_number_from_filepath(
+ "test.1004.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_EQ(tile_number, 1004);
+
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "has_no_number.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.X.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "wrong.1004.png", udim_pattern, tile_format, &tile_number));
+
+ MEM_freeN(udim_pattern);
+
+ /* UVTILE tile format tests. */
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ EXPECT_TRUE(BKE_image_get_tile_number_from_filepath(
+ "test.u2_v2.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_EQ(tile_number, 1012);
+
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "has_no_number.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.u1_vX.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "test.uX_v1.png", udim_pattern, tile_format, &tile_number));
+ EXPECT_FALSE(BKE_image_get_tile_number_from_filepath(
+ "wrong.u2_v2.png", udim_pattern, tile_format, &tile_number));
+
+ MEM_freeN(udim_pattern);
+}
+
+TEST(udim, image_set_filepath_from_tile_number)
+{
+ eUDIM_TILE_FORMAT tile_format;
+ char *udim_pattern;
+
+ udim_pattern = BKE_image_get_tile_strformat("test.<UDIM>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UDIM);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ char filepath[FILE_MAX];
+
+ /* Parameter validation. */
+ BLI_strncpy(filepath, "xxxx", FILE_MAX);
+
+ BKE_image_set_filepath_from_tile_number(nullptr, udim_pattern, tile_format, 1028);
+ BKE_image_set_filepath_from_tile_number(filepath, nullptr, tile_format, 1028);
+ EXPECT_STREQ(filepath, "xxxx");
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, UDIM_TILE_FORMAT_NONE, 1028);
+ EXPECT_STREQ(filepath, "xxxx");
+
+ /* UDIM tile format tests. */
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
+ EXPECT_STREQ(filepath, "test.1028.png");
+ MEM_freeN(udim_pattern);
+
+ /* UVTILE tile format tests. */
+ udim_pattern = BKE_image_get_tile_strformat("test.<UVTILE>.png", &tile_format);
+ EXPECT_EQ(tile_format, UDIM_TILE_FORMAT_UVTILE);
+ EXPECT_NE(udim_pattern, nullptr);
+
+ BKE_image_set_filepath_from_tile_number(filepath, udim_pattern, tile_format, 1028);
+ EXPECT_STREQ(filepath, "test.u8_v3.png");
+ MEM_freeN(udim_pattern);
+}
+
+} // namespace blender::bke::tests
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 782d5442c99..5afc3c0be3b 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -199,7 +199,7 @@ static void mesh_foreach_path(ID *id, BPathForeachPathData *bpath_data)
{
Mesh *me = (Mesh *)id;
if (me->ldata.external) {
- BKE_bpath_foreach_path_fixed_process(bpath_data, me->ldata.external->filename);
+ BKE_bpath_foreach_path_fixed_process(bpath_data, me->ldata.external->filepath);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 40c6fbcf67e..dc9ec002d1a 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -910,18 +910,20 @@ static void curve_to_mesh_eval_ensure(Object &object)
*
* So we create temporary copy of the object which will use same data as the original bevel, but
* will have no modifiers. */
- Object bevel_object = {{nullptr}};
+ Object bevel_object;
+ blender::dna::zero_memory(bevel_object);
if (curve.bevobj != nullptr) {
- memcpy(&bevel_object, curve.bevobj, sizeof(bevel_object));
+ blender::dna::copy_memory(bevel_object, *curve.bevobj);
BLI_listbase_clear(&bevel_object.modifiers);
BKE_object_runtime_reset(&bevel_object);
curve.bevobj = &bevel_object;
}
/* Same thing for taper. */
- Object taper_object = {{nullptr}};
+ Object taper_object;
+ blender::dna::zero_memory(taper_object);
if (curve.taperobj != nullptr) {
- memcpy(&taper_object, curve.taperobj, sizeof(taper_object));
+ blender::dna::copy_memory(taper_object, *curve.taperobj);
BLI_listbase_clear(&taper_object.modifiers);
BKE_object_runtime_reset(&taper_object);
curve.taperobj = &taper_object;
@@ -1066,7 +1068,7 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph,
}
Object object_for_eval;
- memcpy(&object_for_eval, object, sizeof(object_for_eval));
+ blender::dna::copy_memory(object_for_eval, *object);
if (object_for_eval.runtime.data_orig != nullptr) {
object_for_eval.data = object_for_eval.runtime.data_orig;
}
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index da0bd1f021d..6c5a5de31fc 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -695,7 +695,7 @@ static void bm_corners_to_loops_ex(ID *id,
if (CustomData_external_test(fdata, CD_MDISPS)) {
if (id && fdata->external) {
- CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filename);
+ CustomData_external_add(ldata, id, CD_MDISPS, totloop, fdata->external->filepath);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index e9c26c80141..9c4098e2db6 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -561,7 +561,7 @@ void BKE_mesh_origindex_map_create_looptri(MeshElemMap **r_map,
typedef bool (*MeshRemap_CheckIslandBoundary)(const struct MPoly *mpoly,
const struct MLoop *mloop,
const struct MEdge *medge,
- const int nbr_edge_users,
+ const int edge_user_count,
const struct MPoly *mpoly_array,
const struct MeshElemMap *edge_poly_map,
void *user_data);
@@ -764,14 +764,14 @@ static void poly_edge_loop_islands_calc(const MEdge *medge,
static bool poly_is_island_boundary_smooth_cb(const MPoly *mp,
const MLoop *UNUSED(ml),
const MEdge *me,
- const int nbr_edge_users,
+ const int edge_user_count,
const MPoly *mpoly_array,
const MeshElemMap *edge_poly_map,
void *UNUSED(user_data))
{
/* Edge is sharp if one of its polys is flat, or edge itself is sharp,
* or edge is not used by exactly two polygons. */
- if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (nbr_edge_users == 2)) {
+ if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (edge_user_count == 2)) {
/* In that case, edge appears to be smooth, but we need to check its other poly too. */
const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ?
&mpoly_array[edge_poly_map->indices[1]] :
@@ -935,7 +935,7 @@ typedef struct MeshCheckIslandBoundaryUv {
static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
const MLoop *ml,
const MEdge *me,
- const int UNUSED(nbr_edge_users),
+ const int UNUSED(edge_user_count),
const MPoly *UNUSED(mpoly_array),
const MeshElemMap *UNUSED(edge_poly_map),
void *user_data)
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index 7633a3155ba..ba1004e8371 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -532,7 +532,7 @@ void BKE_lnor_spacearr_init(MLoopNorSpaceArray *lnors_spacearr,
lnors_spacearr->loops_pool = (LinkNode *)BLI_memarena_alloc(
mem, sizeof(LinkNode) * (size_t)numLoops);
- lnors_spacearr->num_spaces = 0;
+ lnors_spacearr->spaces_num = 0;
}
BLI_assert(ELEM(data_type, MLNOR_SPACEARR_BMLOOP_PTR, MLNOR_SPACEARR_LOOP_INDEX));
lnors_spacearr->data_type = data_type;
@@ -550,7 +550,7 @@ void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
{
BLI_assert(lnors_spacearr->data_type == lnors_spacearr_tls->data_type);
BLI_assert(lnors_spacearr->mem != lnors_spacearr_tls->mem);
- lnors_spacearr->num_spaces += lnors_spacearr_tls->num_spaces;
+ lnors_spacearr->spaces_num += lnors_spacearr_tls->spaces_num;
BLI_memarena_merge(lnors_spacearr->mem, lnors_spacearr_tls->mem);
BLI_memarena_free(lnors_spacearr_tls->mem);
lnors_spacearr_tls->mem = nullptr;
@@ -559,7 +559,7 @@ void BKE_lnor_spacearr_tls_join(MLoopNorSpaceArray *lnors_spacearr,
void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
{
- lnors_spacearr->num_spaces = 0;
+ lnors_spacearr->spaces_num = 0;
lnors_spacearr->lspacearr = nullptr;
lnors_spacearr->loops_pool = nullptr;
if (lnors_spacearr->mem != nullptr) {
@@ -569,7 +569,7 @@ void BKE_lnor_spacearr_clear(MLoopNorSpaceArray *lnors_spacearr)
void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
{
- lnors_spacearr->num_spaces = 0;
+ lnors_spacearr->spaces_num = 0;
lnors_spacearr->lspacearr = nullptr;
lnors_spacearr->loops_pool = nullptr;
BLI_memarena_free(lnors_spacearr->mem);
@@ -578,7 +578,7 @@ void BKE_lnor_spacearr_free(MLoopNorSpaceArray *lnors_spacearr)
MLoopNorSpace *BKE_lnor_space_create(MLoopNorSpaceArray *lnors_spacearr)
{
- lnors_spacearr->num_spaces++;
+ lnors_spacearr->spaces_num++;
return (MLoopNorSpace *)BLI_memarena_calloc(lnors_spacearr->mem, sizeof(MLoopNorSpace));
}
@@ -613,19 +613,19 @@ void BKE_lnor_space_define(MLoopNorSpace *lnor_space,
/* Compute ref alpha, average angle of all available edge vectors to lnor. */
if (edge_vectors) {
float alpha = 0.0f;
- int nbr = 0;
+ int count = 0;
while (!BLI_stack_is_empty(edge_vectors)) {
const float *vec = (const float *)BLI_stack_peek(edge_vectors);
alpha += saacosf(dot_v3v3(vec, lnor));
BLI_stack_discard(edge_vectors);
- nbr++;
+ count++;
}
- /* NOTE: In theory, this could be `nbr > 2`,
+ /* NOTE: In theory, this could be `count > 2`,
* but there is one case where we only have two edges for two loops:
* a smooth vertex with only two edges and two faces (our Monkey's nose has that, e.g.).
*/
- BLI_assert(nbr >= 2); /* This piece of code shall only be called for more than one loop. */
- lnor_space->ref_alpha = alpha / (float)nbr;
+ BLI_assert(count >= 2); /* This piece of code shall only be called for more than one loop. */
+ lnor_space->ref_alpha = alpha / (float)count;
}
else {
lnor_space->ref_alpha = (saacosf(dot_v3v3(vec_ref, lnor)) +
@@ -1134,7 +1134,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
/* We validate clnors data on the fly - cheapest way to do! */
int clnors_avg[2] = {0, 0};
short(*clnor_ref)[2] = nullptr;
- int clnors_nbr = 0;
+ int clnors_count = 0;
bool clnors_invalid = false;
/* Temp loop normal stack. */
@@ -1194,7 +1194,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
if (clnors_data) {
/* Accumulate all clnors, if they are not all equal we have to fix that! */
short(*clnor)[2] = &clnors_data[mlfan_vert_index];
- if (clnors_nbr) {
+ if (clnors_count) {
clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
}
else {
@@ -1202,7 +1202,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
}
clnors_avg[0] += (*clnor)[0];
clnors_avg[1] += (*clnor)[1];
- clnors_nbr++;
+ clnors_count++;
/* We store here a pointer to all custom lnors processed. */
BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
}
@@ -1262,8 +1262,8 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli
if (clnors_invalid) {
short *clnor;
- clnors_avg[0] /= clnors_nbr;
- clnors_avg[1] /= clnors_nbr;
+ clnors_avg[0] /= clnors_count;
+ clnors_avg[1] /= clnors_count;
/* Fix/update all clnors of this fan with computed average value. */
if (G.debug & G_DEBUG) {
printf("Invalid clnors in this fan!\n");
@@ -1952,7 +1952,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
BLI_BITMAP_DISABLE(done_loops, i);
}
else {
- int nbr_nors = 0;
+ int avg_nor_count = 0;
float avg_nor[3];
short clnor_data_tmp[2], *clnor_data;
@@ -1962,7 +1962,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
const int nidx = use_vertices ? (int)mloops[lidx].v : lidx;
float *nor = r_custom_loopnors[nidx];
- nbr_nors++;
+ avg_nor_count++;
add_v3_v3(avg_nor, nor);
BLI_SMALLSTACK_PUSH(clnors_data, (short *)r_clnors_data[lidx]);
@@ -1970,7 +1970,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
BLI_BITMAP_DISABLE(done_loops, lidx);
}
- mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors);
+ mul_v3_fl(avg_nor, 1.0f / (float)avg_nor_count);
BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], avg_nor, clnor_data_tmp);
while ((clnor_data = (short *)BLI_SMALLSTACK_POP(clnors_data))) {
@@ -2088,8 +2088,8 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts,
const float (*clnors)[3],
float (*r_vert_clnors)[3])
{
- int *vert_loops_nbr = (int *)MEM_calloc_arrayN(
- (size_t)numVerts, sizeof(*vert_loops_nbr), __func__);
+ int *vert_loops_count = (int *)MEM_calloc_arrayN(
+ (size_t)numVerts, sizeof(*vert_loops_count), __func__);
copy_vn_fl((float *)r_vert_clnors, 3 * numVerts, 0.0f);
@@ -2099,14 +2099,14 @@ void BKE_mesh_normals_loop_to_vertex(const int numVerts,
const uint v = ml->v;
add_v3_v3(r_vert_clnors[v], clnors[i]);
- vert_loops_nbr[v]++;
+ vert_loops_count[v]++;
}
for (i = 0; i < numVerts; i++) {
- mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_nbr[i]);
+ mul_v3_fl(r_vert_clnors[i], 1.0f / (float)vert_loops_count[i]);
}
- MEM_freeN(vert_loops_nbr);
+ MEM_freeN(vert_loops_count);
}
#undef LNOR_SPACE_TRIGO_THRESHOLD
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 4374659bff8..6af765d7de5 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -577,7 +577,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
else if (mp->loopstart + mp->totloop > totloop) {
/* Invalid loop data. */
PRINT_ERR(
- "\tPoly %u uses loops out of range (loopstart: %d, loopend: %d, max nbr of loops: %u)",
+ "\tPoly %u uses loops out of range "
+ "(loopstart: %d, loopend: %d, max number of loops: %u)",
sp->index,
mp->loopstart,
mp->loopstart + mp->totloop - 1,
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 1e3b5d77fa7..4714a79de58 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -766,7 +766,7 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
hmd->indexar = hook->indexar;
hmd->object = hook->parent;
memcpy(hmd->parentinv, hook->parentinv, sizeof(hmd->parentinv));
- hmd->totindex = hook->totindex;
+ hmd->indexar_num = hook->totindex;
BLI_addhead(&ob->modifiers, hmd);
BLI_remlink(&ob->hooks, hook);
@@ -1236,7 +1236,7 @@ IDTypeInfo IDType_ID_OB = {
void BKE_object_workob_clear(Object *workob)
{
- memset(workob, 0, sizeof(Object));
+ blender::dna::zero_memory(*workob);
workob->scale[0] = workob->scale[1] = workob->scale[2] = 1.0f;
workob->dscale[0] = workob->dscale[1] = workob->dscale[2] = 1.0f;
@@ -3946,7 +3946,7 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
/* pass */
}
else {
- Object temp_ob = *dob->ob;
+ Object temp_ob = blender::dna::shallow_copy(*dob->ob);
/* Do not modify the original boundbox. */
temp_ob.runtime.bb = nullptr;
BKE_object_replace_data_on_shallow_copy(&temp_ob, dob->ob_data);
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 4c5fefefd8e..e7ed100ed03 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -174,16 +174,16 @@ PackedFile *BKE_packedfile_new_from_memory(void *mem, int memlen)
return pf;
}
-PackedFile *BKE_packedfile_new(ReportList *reports, const char *filename, const char *basepath)
+PackedFile *BKE_packedfile_new(ReportList *reports, const char *filepath, const char *basepath)
{
PackedFile *pf = NULL;
int file, filelen;
char name[FILE_MAX];
void *data;
- /* render result has no filename and can be ignored
+ /* render result has no filepath and can be ignored
* any other files with no name can be ignored too */
- if (filename[0] == '\0') {
+ if (filepath[0] == '\0') {
return pf;
}
@@ -191,7 +191,7 @@ PackedFile *BKE_packedfile_new(ReportList *reports, const char *filename, const
/* convert relative filenames to absolute filenames */
- BLI_strncpy(name, filename, sizeof(name));
+ BLI_strncpy(name, filepath, sizeof(name));
BLI_path_abs(name, basepath);
/* open the file
@@ -285,7 +285,7 @@ void BKE_packedfile_pack_all(Main *bmain, ReportList *reports, bool verbose)
int BKE_packedfile_write_to_file(ReportList *reports,
const char *ref_file_name,
- const char *filename,
+ const char *filepath,
PackedFile *pf,
const bool guimode)
{
@@ -299,7 +299,7 @@ int BKE_packedfile_write_to_file(ReportList *reports,
if (guimode) {
} // XXX waitcursor(1);
- BLI_strncpy(name, filename, sizeof(name));
+ BLI_strncpy(name, filepath, sizeof(name));
BLI_path_abs(name, ref_file_name);
if (BLI_exists(name)) {
@@ -358,7 +358,7 @@ int BKE_packedfile_write_to_file(ReportList *reports,
}
enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name,
- const char *filename,
+ const char *filepath,
PackedFile *pf)
{
BLI_stat_t st;
@@ -366,7 +366,7 @@ enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name,
char buf[4096];
char name[FILE_MAX];
- BLI_strncpy(name, filename, sizeof(name));
+ BLI_strncpy(name, filepath, sizeof(name));
BLI_path_abs(name, ref_file_name);
if (BLI_stat(name, &st) == -1) {
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index c47b22dcd34..9ea1336a95a 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -2661,8 +2661,8 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params
int from = PART_FROM_FACE;
totparent = (int)(totchild * part->parents * 0.3f);
- if (use_render_params && part->child_nbr && part->ren_child_nbr) {
- totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
+ if (use_render_params && part->child_percent && part->child_render_percent) {
+ totparent *= (float)part->child_percent / (float)part->child_render_percent;
}
/* hard limit, workaround for it being ignored above */
@@ -2736,8 +2736,8 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx,
if (totchild && part->childtype == PART_CHILD_FACES) {
totparent = (int)(totchild * part->parents * 0.3f);
- if (use_render_params && part->child_nbr && part->ren_child_nbr) {
- totparent *= (float)part->child_nbr / (float)part->ren_child_nbr;
+ if (use_render_params && part->child_percent && part->child_render_percent) {
+ totparent *= (float)part->child_percent / (float)part->child_render_percent;
}
/* part->parents could still be 0 so we can't test with totparent */
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 83fb52ce1ef..d2c3776d4ea 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -64,14 +64,14 @@ static void distribute_simple_children(Scene *scene,
{
ChildParticle *cpa = NULL;
int i, p;
- int child_nbr = psys_get_child_number(scene, psys, use_render_params);
- int totpart = psys_get_tot_child(scene, psys, use_render_params);
+ const int child_num = psys_get_child_number(scene, psys, use_render_params);
+ const int totpart = psys_get_tot_child(scene, psys, use_render_params);
RNG *rng = BLI_rng_new_srandom(31415926 + psys->seed + psys->child_seed);
alloc_child_particles(psys, totpart);
cpa = psys->child;
- for (i = 0; i < child_nbr; i++) {
+ for (i = 0; i < child_num; i++) {
for (p = 0; p < psys->totpart; p++, cpa++) {
float length = 2.0;
cpa->parent = p;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 3a1aefec2d3..7fdc60a265b 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -98,9 +98,9 @@ float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_r
ParticleSettings *part = psys->part;
if ((use_render_params &&
- !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */
- (part->child_nbr && part->childtype) || /* display percentage applies to children */
- (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */
+ !particles_are_dynamic(psys)) || /* non-dynamic particles can be rendered fully */
+ (part->child_percent && part->childtype) || /* display percentage applies to children */
+ (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */
{
return 1.0f;
}
@@ -280,20 +280,20 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
int psys_get_child_number(Scene *scene, ParticleSystem *psys, const bool use_render_params)
{
- int nbr;
+ int child_num;
if (!psys->part->childtype) {
return 0;
}
if (use_render_params) {
- nbr = psys->part->ren_child_nbr;
+ child_num = psys->part->child_render_percent;
}
else {
- nbr = psys->part->child_nbr;
+ child_num = psys->part->child_percent;
}
- return get_render_child_particle_number(&scene->r, nbr, use_render_params);
+ return get_render_child_particle_number(&scene->r, child_num, use_render_params);
}
int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render_params)
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.cc
index 6797538d190..cebe4482eb7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.cc
@@ -8,9 +8,9 @@
/* Allow using deprecated functionality for .blend file I/O. */
#define DNA_DEPRECATED_ALLOW
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
#include "MEM_guardedalloc.h"
@@ -183,11 +183,11 @@ static void scene_init_data(ID *id)
/* multiview - stereo */
BKE_scene_add_render_view(scene, STEREO_LEFT_NAME);
- srv = scene->r.views.first;
+ srv = static_cast<SceneRenderView *>(scene->r.views.first);
BLI_strncpy(srv->suffix, STEREO_LEFT_SUFFIX, sizeof(srv->suffix));
BKE_scene_add_render_view(scene, STEREO_RIGHT_NAME);
- srv = scene->r.views.last;
+ srv = static_cast<SceneRenderView *>(scene->r.views.last);
BLI_strncpy(srv->suffix, STEREO_RIGHT_SUFFIX, sizeof(srv->suffix));
BKE_sound_reset_scene_runtime(scene);
@@ -218,14 +218,14 @@ static void scene_init_data(ID *id)
/* Master Collection */
scene->master_collection = BKE_collection_master_add();
- BKE_view_layer_add(scene, "ViewLayer", NULL, VIEWLAYER_ADD_NEW);
+ BKE_view_layer_add(scene, "ViewLayer", nullptr, VIEWLAYER_ADD_NEW);
}
static void scene_copy_markers(Scene *scene_dst, const Scene *scene_src, const int flag)
{
BLI_duplicatelist(&scene_dst->markers, &scene_src->markers);
LISTBASE_FOREACH (TimeMarker *, marker, &scene_dst->markers) {
- if (marker->prop != NULL) {
+ if (marker->prop != nullptr) {
marker->prop = IDP_CopyProperty_ex(marker->prop, flag);
}
}
@@ -240,9 +240,9 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
/* We always need allocation of our private ID data. */
const int flag_private_id_data = flag & ~LIB_ID_CREATE_NO_ALLOCATE;
- scene_dst->ed = NULL;
- scene_dst->depsgraph_hash = NULL;
- scene_dst->fps_info = NULL;
+ scene_dst->ed = nullptr;
+ scene_dst->depsgraph_hash = nullptr;
+ scene_dst->fps_info = nullptr;
/* Master Collection */
if (scene_src->master_collection) {
@@ -254,8 +254,8 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
/* View Layers */
BLI_duplicatelist(&scene_dst->view_layers, &scene_src->view_layers);
- for (ViewLayer *view_layer_src = scene_src->view_layers.first,
- *view_layer_dst = scene_dst->view_layers.first;
+ for (ViewLayer *view_layer_src = static_cast<ViewLayer *>(scene_src->view_layers.first),
+ *view_layer_dst = static_cast<ViewLayer *>(scene_dst->view_layers.first);
view_layer_src;
view_layer_src = view_layer_src->next, view_layer_dst = view_layer_dst->next) {
BKE_view_layer_copy_data(scene_dst, scene_src, view_layer_dst, view_layer_src, flag_subdata);
@@ -299,7 +299,8 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
/* make a private copy of the avicodecdata */
if (scene_src->r.avicodecdata) {
- scene_dst->r.avicodecdata = MEM_dupallocN(scene_src->r.avicodecdata);
+ scene_dst->r.avicodecdata = static_cast<AviCodecData *>(
+ MEM_dupallocN(scene_src->r.avicodecdata));
scene_dst->r.avicodecdata->lpFormat = MEM_dupallocN(scene_dst->r.avicodecdata->lpFormat);
scene_dst->r.avicodecdata->lpParms = MEM_dupallocN(scene_dst->r.avicodecdata->lpParms);
}
@@ -312,7 +313,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
/* Copy sequencer, this is local data! */
if (scene_src->ed) {
- scene_dst->ed = MEM_callocN(sizeof(*scene_dst->ed), __func__);
+ scene_dst->ed = MEM_cnew<Editing>(__func__);
scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
SEQ_sequence_base_dupli_recursive(scene_src,
scene_dst,
@@ -326,7 +327,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
BKE_previewimg_id_copy(&scene_dst->id, &scene_src->id);
}
else {
- scene_dst->preview = NULL;
+ scene_dst->preview = nullptr;
}
BKE_scene_copy_data_eevee(scene_dst, scene_src);
@@ -335,7 +336,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
static void scene_free_markers(Scene *scene, bool do_id_user)
{
LISTBASE_FOREACH_MUTABLE (TimeMarker *, marker, &scene->markers) {
- if (marker->prop != NULL) {
+ if (marker->prop != nullptr) {
IDP_FreePropertyContent_ex(marker->prop, do_id_user);
MEM_freeN(marker->prop);
}
@@ -357,22 +358,22 @@ static void scene_free_data(ID *id)
if (scene->nodetree) {
ntreeFreeEmbeddedTree(scene->nodetree);
MEM_freeN(scene->nodetree);
- scene->nodetree = NULL;
+ scene->nodetree = nullptr;
}
if (scene->rigidbody_world) {
/* Prevent rigidbody freeing code to follow other IDs pointers, this should never be allowed
* nor necessary from here, and with new undo code, those pointers may be fully invalid or
* worse, pointing to data actually belonging to new BMain! */
- scene->rigidbody_world->constraints = NULL;
- scene->rigidbody_world->group = NULL;
+ scene->rigidbody_world->constraints = nullptr;
+ scene->rigidbody_world->group = nullptr;
BKE_rigidbody_free_world(scene);
}
if (scene->r.avicodecdata) {
free_avicodecdata(scene->r.avicodecdata);
MEM_freeN(scene->r.avicodecdata);
- scene->r.avicodecdata = NULL;
+ scene->r.avicodecdata = nullptr;
}
scene_free_markers(scene, do_id_user);
@@ -380,7 +381,7 @@ static void scene_free_data(ID *id)
BLI_freelistN(&scene->r.views);
BKE_toolsettings_free(scene->toolsettings);
- scene->toolsettings = NULL;
+ scene->toolsettings = nullptr;
BKE_scene_free_depsgraph_hash(scene);
@@ -395,10 +396,7 @@ static void scene_free_data(ID *id)
BKE_previewimg_free(&scene->preview);
BKE_curvemapping_free_data(&scene->r.mblur_shutter_curve);
- for (ViewLayer *view_layer = scene->view_layers.first, *view_layer_next; view_layer;
- view_layer = view_layer_next) {
- view_layer_next = view_layer->next;
-
+ LISTBASE_FOREACH_MUTABLE (ViewLayer *, view_layer, &scene->view_layers) {
BLI_remlink(&scene->view_layers, view_layer);
BKE_view_layer_free_ex(view_layer, do_id_user);
}
@@ -412,21 +410,21 @@ static void scene_free_data(ID *id)
BKE_collection_free_data(scene->master_collection);
BKE_libblock_free_data_py(&scene->master_collection->id);
MEM_freeN(scene->master_collection);
- scene->master_collection = NULL;
+ scene->master_collection = nullptr;
}
if (scene->eevee.light_cache_data) {
EEVEE_lightcache_free(scene->eevee.light_cache_data);
- scene->eevee.light_cache_data = NULL;
+ scene->eevee.light_cache_data = nullptr;
}
if (scene->display.shading.prop) {
IDP_FreeProperty(scene->display.shading.prop);
- scene->display.shading.prop = NULL;
+ scene->display.shading.prop = nullptr;
}
/* These are freed on doversion. */
- BLI_assert(scene->layer_properties == NULL);
+ BLI_assert(scene->layer_properties == nullptr);
}
static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSED(rbw),
@@ -443,14 +441,14 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE
* This code is shared by both the regular `foreach_id` looper, and the code trying to restore or
* preserve ID pointers like brushes across undo-steps.
*/
-typedef enum eSceneForeachUndoPreserveProcess {
+enum eSceneForeachUndoPreserveProcess {
/* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID
* pointer from its old scene's value. */
SCENE_FOREACH_UNDO_RESTORE,
/* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID
* pointer. */
SCENE_FOREACH_UNDO_NO_RESTORE,
-} eSceneForeachUndoPreserveProcess;
+};
static void scene_foreach_toolsettings_id_pointer_process(
ID **id_p,
@@ -464,9 +462,10 @@ static void scene_foreach_toolsettings_id_pointer_process(
ID *id_old = *id_old_p;
/* Old data has not been remapped to new values of the pointers, if we want to keep the old
* pointer here we need its new address. */
- ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
- NULL;
- if (id_old_new != NULL) {
+ ID *id_old_new = id_old != nullptr ?
+ BLO_read_get_new_id_address(reader, id_old->lib, id_old) :
+ nullptr;
+ if (id_old_new != nullptr) {
BLI_assert(ELEM(id_old, id_old_new, id_old_new->orig_id));
*id_old_p = id_old_new;
if (cb_flag & IDWALK_CB_USER) {
@@ -489,7 +488,7 @@ static void scene_foreach_toolsettings_id_pointer_process(
/* Special handling is needed here, as `scene_foreach_toolsettings` (and its dependency
* `scene_foreach_paint`) are also used by `scene_undo_preserve`, where `LibraryForeachIDData
- * *data` is NULL. */
+ * *data` is nullptr. */
#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER( \
__data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \
{ \
@@ -498,7 +497,7 @@ static void scene_foreach_toolsettings_id_pointer_process(
(ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \
} \
else { \
- BLI_assert((__data) != NULL); \
+ BLI_assert((__data) != nullptr); \
BKE_LIB_FOREACHID_PROCESS_IDSUPER(__data, __id, __cb_flag); \
} \
} \
@@ -511,7 +510,7 @@ static void scene_foreach_toolsettings_id_pointer_process(
__func_call; \
} \
else { \
- BLI_assert((__data) != NULL); \
+ BLI_assert((__data) != nullptr); \
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(__data, __func_call); \
} \
} \
@@ -536,10 +535,10 @@ static void scene_foreach_paint(LibraryForeachIDData *data,
* this is equivalent to simply looping over slots from `paint`.
* - In case we do `undo_restore`, we only want to consider the slots from the old one, since
* those are the one we keep in the end.
- * + In case the new data has less valid slots, we feed in a dummy NULL pointer.
+ * + In case the new data has less valid slots, we feed in a dummy null pointer.
* + In case the new data has more valid slots, the extra ones are ignored.
*/
- Brush *brush_tmp = NULL;
+ Brush *brush_tmp = nullptr;
Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp;
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER(data,
*brush_p,
@@ -725,7 +724,7 @@ static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
/* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad
* anyway... */
- const int cb_flag = (lc->collection != NULL &&
+ const int cb_flag = (lc->collection != nullptr &&
(lc->collection->id.flag & LIB_EMBEDDED_DATA) != 0) ?
IDWALK_CB_EMBEDDED :
IDWALK_CB_NOP;
@@ -760,7 +759,7 @@ static bool seq_foreach_member_id_cb(Sequence *seq, void *user_data)
}
if (seq->type == SEQ_TYPE_TEXT && seq->effectdata) {
- TextVars *text_data = seq->effectdata;
+ TextVars *text_data = static_cast<TextVars *>(seq->effectdata);
FOREACHID_PROCESS_IDSUPER(data, text_data->text_font, IDWALK_CB_USER);
}
@@ -792,8 +791,8 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
BKE_keyingsets_foreach_id(data, &scene->keyingsets));
- /* This pointer can be NULL during old files reading, better be safe than sorry. */
- if (scene->master_collection != NULL) {
+ /* This pointer can be nullptr during old files reading, better be safe than sorry. */
+ if (scene->master_collection != nullptr) {
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
data, BKE_library_foreach_ID_embedded(data, (ID **)&scene->master_collection));
}
@@ -839,7 +838,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
ToolSettings *toolsett = scene->toolsettings;
if (toolsett) {
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
- data, scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett));
+ data, scene_foreach_toolsettings(data, toolsett, false, nullptr, toolsett));
}
if (scene->rigidbody_world) {
@@ -855,11 +854,10 @@ static void scene_foreach_cache(ID *id,
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,
- };
+ IDCacheKey key{};
+ key.id_session_uuid = id->session_uuid;
+ key.offset_in_ID = offsetof(Scene, eevee.light_cache_data);
+ key.cache_v = scene->eevee.light_cache_data;
function_callback(id,
&key,
@@ -902,7 +900,7 @@ static bool seq_foreach_path_callback(Sequence *seq, void *user_data)
static void scene_foreach_path(ID *id, BPathForeachPathData *bpath_data)
{
Scene *scene = (Scene *)id;
- if (scene->ed != NULL) {
+ if (scene->ed != nullptr) {
SEQ_for_each_callback(&scene->ed->seqbase, seq_foreach_path_callback, bpath_data);
}
}
@@ -1012,7 +1010,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
LISTBASE_FOREACH (TimeMarker *, marker, &sce->markers) {
BLO_write_struct(writer, TimeMarker, marker);
- if (marker->prop != NULL) {
+ if (marker->prop != nullptr) {
IDP_BlendWrite(writer, marker->prop);
}
}
@@ -1069,7 +1067,7 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
BKE_screen_view3d_shading_blend_write(writer, &sce->display.shading);
/* Freed on doversion. */
- BLI_assert(sce->layer_properties == NULL);
+ BLI_assert(sce->layer_properties == nullptr);
}
static void direct_link_paint_helper(BlendDataReader *reader, const Scene *scene, Paint **paint)
@@ -1102,8 +1100,8 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
{
Scene *sce = (Scene *)id;
- sce->depsgraph_hash = NULL;
- sce->fps_info = NULL;
+ sce->depsgraph_hash = nullptr;
+ sce->fps_info = nullptr;
memset(&sce->customdata_mask, 0, sizeof(sce->customdata_mask));
memset(&sce->customdata_mask_modal, 0, sizeof(sce->customdata_mask_modal));
@@ -1144,10 +1142,10 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BKE_paint_blend_read_data(reader, sce, &sce->toolsettings->imapaint.paint);
- sce->toolsettings->particle.paintcursor = NULL;
- sce->toolsettings->particle.scene = NULL;
- sce->toolsettings->particle.object = NULL;
- sce->toolsettings->gp_sculpt.paintcursor = NULL;
+ sce->toolsettings->particle.paintcursor = nullptr;
+ sce->toolsettings->particle.scene = nullptr;
+ sce->toolsettings->particle.object = nullptr;
+ sce->toolsettings->gp_sculpt.paintcursor = nullptr;
/* relink grease pencil interpolation curves */
BLO_read_data_address(reader, &sce->toolsettings->gp_interpolate.custom_ipo);
@@ -1181,9 +1179,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
Editing *ed = sce->ed;
BLO_read_data_address(reader, &ed->act_seq);
- ed->cache = NULL;
- ed->prefetch_job = NULL;
- ed->runtime.sequence_lookup = NULL;
+ ed->cache = nullptr;
+ ed->prefetch_job = nullptr;
+ ed->runtime.sequence_lookup = nullptr;
/* recursive link sequences, lb will be correctly initialized */
link_recurs_seq(reader, &ed->seqbase);
@@ -1275,9 +1273,9 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
if (rbw) {
BLO_read_data_address(reader, &rbw->shared);
- if (rbw->shared == NULL) {
+ if (rbw->shared == nullptr) {
/* Link deprecated caches if they exist, so we can use them for versioning.
- * We should only do this when rbw->shared == NULL, because those pointers
+ * We should only do this when rbw->shared == nullptr, because those pointers
* are always set (for compatibility with older Blenders). We mustn't link
* the same pointcache twice. */
BKE_ptcache_blend_read_data(reader, &rbw->ptcaches, &rbw->pointcache, false);
@@ -1291,7 +1289,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
/* must nullify the reference to physics sim object, since it no-longer exist
* (and will need to be recalculated)
*/
- rbw->shared->physics_world = NULL;
+ rbw->shared->physics_world = nullptr;
/* link caches */
BKE_ptcache_blend_read_data(reader, &rbw->shared->ptcaches, &rbw->shared->pointcache, false);
@@ -1301,13 +1299,13 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
rbw->ltime = (float)rbw->shared->pointcache->startframe;
}
}
- rbw->objects = NULL;
+ rbw->objects = nullptr;
rbw->numbodies = 0;
/* set effector weights */
BLO_read_data_address(reader, &rbw->effector_weights);
if (!rbw->effector_weights) {
- rbw->effector_weights = BKE_effector_add_weights(NULL);
+ rbw->effector_weights = BKE_effector_add_weights(nullptr);
}
}
@@ -1352,7 +1350,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
static void composite_patch(bNodeTree *ntree, Scene *scene)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->id == NULL &&
+ if (node->id == nullptr &&
((node->type == CMP_NODE_R_LAYERS) ||
(node->type == CMP_NODE_CRYPTOMATTE && node->custom1 == CMP_CRYPTOMATTE_SRC_RENDER))) {
node->id = &scene->id;
@@ -1423,14 +1421,14 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
LISTBASE_FOREACH_MUTABLE (Base *, base_legacy, &sce->base) {
BLO_read_id_address(reader, sce->id.lib, &base_legacy->object);
- if (base_legacy->object == NULL) {
+ if (base_legacy->object == nullptr) {
BLO_reportf_wrap(BLO_read_lib_reports(reader),
RPT_WARNING,
TIP_("LIB: object lost from scene: '%s'"),
sce->id.name + 2);
BLI_remlink(&sce->base, base_legacy);
if (base_legacy == sce->basact) {
- sce->basact = NULL;
+ sce->basact = nullptr;
}
MEM_freeN(base_legacy);
}
@@ -1494,7 +1492,7 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
}
#ifdef USE_SETSCENE_CHECK
- if (sce->set != NULL) {
+ if (sce->set != nullptr) {
sce->flag |= SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK;
}
#endif
@@ -1588,12 +1586,12 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old)
Scene *scene_old = (Scene *)id_old;
SWAP(View3DCursor, scene_old->cursor, scene_new->cursor);
- if (scene_new->toolsettings != NULL && scene_old->toolsettings != NULL) {
+ if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) {
/* First try to restore ID pointers that can be and should be preserved (like brushes or
* palettes), and counteract the swap of the whole ToolSettings structs below for the others
* (like object ones). */
scene_foreach_toolsettings(
- NULL, scene_new->toolsettings, true, reader, scene_old->toolsettings);
+ nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings);
SWAP(ToolSettings, *scene_old->toolsettings, *scene_new->toolsettings);
}
}
@@ -1602,46 +1600,50 @@ static void scene_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src))
{
Scene *scene = (Scene *)id_dst;
- if (scene->rigidbody_world != NULL) {
+ if (scene->rigidbody_world != nullptr) {
PTCacheID pid;
- BKE_ptcache_id_from_rigidbody(&pid, NULL, scene->rigidbody_world);
+ BKE_ptcache_id_from_rigidbody(&pid, nullptr, scene->rigidbody_world);
LISTBASE_FOREACH (PointCache *, point_cache, pid.ptcaches) {
point_cache->flag |= PTCACHE_FLAG_INFO_DIRTY;
}
}
}
-IDTypeInfo IDType_ID_SCE = {
- .id_code = ID_SCE,
- .id_filter = FILTER_ID_SCE,
- .main_listbase_index = INDEX_ID_SCE,
- .struct_size = sizeof(Scene),
- .name = "Scene",
- .name_plural = "scenes",
- .translation_context = BLT_I18NCONTEXT_ID_SCENE,
- .flags = 0,
- .asset_type_info = NULL,
+constexpr IDTypeInfo get_type_info()
+{
+ IDTypeInfo info{};
+ info.id_code = ID_SCE;
+ info.id_filter = FILTER_ID_SCE;
+ info.main_listbase_index = INDEX_ID_SCE;
+ info.struct_size = sizeof(Scene);
+ info.name = "Scene";
+ info.name_plural = "scenes";
+ info.translation_context = BLT_I18NCONTEXT_ID_SCENE;
+ info.flags = 0;
+ info.asset_type_info = nullptr;
- .init_data = scene_init_data,
- .copy_data = scene_copy_data,
- .free_data = scene_free_data,
- /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
- * support all possible corner cases. */
- .make_local = NULL,
- .foreach_id = scene_foreach_id,
- .foreach_cache = scene_foreach_cache,
- .foreach_path = scene_foreach_path,
- .owner_get = NULL,
+ info.init_data = scene_init_data;
+ info.copy_data = scene_copy_data;
+ info.free_data = scene_free_data;
+ /* For now default `BKE_lib_id_make_local_generic()` should work, may need more work though to
+ * support all possible corner cases. */
+ info.make_local = nullptr;
+ info.foreach_id = scene_foreach_id;
+ info.foreach_cache = scene_foreach_cache;
+ info.foreach_path = scene_foreach_path;
+ info.owner_get = nullptr;
- .blend_write = scene_blend_write,
- .blend_read_data = scene_blend_read_data,
- .blend_read_lib = scene_blend_read_lib,
- .blend_read_expand = scene_blend_read_expand,
+ info.blend_write = scene_blend_write;
+ info.blend_read_data = scene_blend_read_data;
+ info.blend_read_lib = scene_blend_read_lib;
+ info.blend_read_expand = scene_blend_read_expand;
- .blend_read_undo_preserve = scene_undo_preserve,
+ info.blend_read_undo_preserve = scene_undo_preserve;
- .lib_override_apply_post = scene_lib_override_apply_post,
-};
+ info.lib_override_apply_post = scene_lib_override_apply_post;
+ return info;
+}
+IDTypeInfo IDType_ID_SCE = get_type_info();
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
@@ -1652,12 +1654,12 @@ void free_avicodecdata(AviCodecData *acd)
if (acd) {
if (acd->lpFormat) {
MEM_freeN(acd->lpFormat);
- acd->lpFormat = NULL;
+ acd->lpFormat = nullptr;
acd->cbFormat = 0;
}
if (acd->lpParms) {
MEM_freeN(acd->lpParms);
- acd->lpParms = NULL;
+ acd->lpParms = nullptr;
acd->cbParms = 0;
}
}
@@ -1668,11 +1670,7 @@ static void remove_sequencer_fcurves(Scene *sce)
AnimData *adt = BKE_animdata_from_id(&sce->id);
if (adt && adt->action) {
- FCurve *fcu, *nextfcu;
-
- for (fcu = adt->action->curves.first; fcu; fcu = nextfcu) {
- nextfcu = fcu->next;
-
+ LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->action->curves) {
if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
action_groups_remove_channel(adt->action, fcu);
BKE_fcurve_free(fcu);
@@ -1683,51 +1681,51 @@ static void remove_sequencer_fcurves(Scene *sce)
ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
{
- if (toolsettings == NULL) {
- return NULL;
+ if (toolsettings == nullptr) {
+ return nullptr;
}
- ToolSettings *ts = MEM_dupallocN(toolsettings);
+ ToolSettings *ts = static_cast<ToolSettings *>(MEM_dupallocN(toolsettings));
if (ts->vpaint) {
- ts->vpaint = MEM_dupallocN(ts->vpaint);
+ ts->vpaint = static_cast<VPaint *>(MEM_dupallocN(ts->vpaint));
BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag);
}
if (ts->wpaint) {
- ts->wpaint = MEM_dupallocN(ts->wpaint);
+ ts->wpaint = static_cast<VPaint *>(MEM_dupallocN(ts->wpaint));
BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag);
}
if (ts->sculpt) {
- ts->sculpt = MEM_dupallocN(ts->sculpt);
+ ts->sculpt = static_cast<Sculpt *>(MEM_dupallocN(ts->sculpt));
BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag);
}
if (ts->uvsculpt) {
- ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
+ ts->uvsculpt = static_cast<UvSculpt *>(MEM_dupallocN(ts->uvsculpt));
BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag);
}
if (ts->gp_paint) {
- ts->gp_paint = MEM_dupallocN(ts->gp_paint);
+ ts->gp_paint = static_cast<GpPaint *>(MEM_dupallocN(ts->gp_paint));
BKE_paint_copy(&ts->gp_paint->paint, &ts->gp_paint->paint, flag);
}
if (ts->gp_vertexpaint) {
- ts->gp_vertexpaint = MEM_dupallocN(ts->gp_vertexpaint);
+ ts->gp_vertexpaint = static_cast<GpVertexPaint *>(MEM_dupallocN(ts->gp_vertexpaint));
BKE_paint_copy(&ts->gp_vertexpaint->paint, &ts->gp_vertexpaint->paint, flag);
}
if (ts->gp_sculptpaint) {
- ts->gp_sculptpaint = MEM_dupallocN(ts->gp_sculptpaint);
+ ts->gp_sculptpaint = static_cast<GpSculptPaint *>(MEM_dupallocN(ts->gp_sculptpaint));
BKE_paint_copy(&ts->gp_sculptpaint->paint, &ts->gp_sculptpaint->paint, flag);
}
if (ts->gp_weightpaint) {
- ts->gp_weightpaint = MEM_dupallocN(ts->gp_weightpaint);
+ ts->gp_weightpaint = static_cast<GpWeightPaint *>(MEM_dupallocN(ts->gp_weightpaint));
BKE_paint_copy(&ts->gp_weightpaint->paint, &ts->gp_weightpaint->paint, flag);
}
if (ts->curves_sculpt) {
- ts->curves_sculpt = MEM_dupallocN(ts->curves_sculpt);
+ ts->curves_sculpt = static_cast<CurvesSculpt *>(MEM_dupallocN(ts->curves_sculpt));
BKE_paint_copy(&ts->curves_sculpt->paint, &ts->curves_sculpt->paint, flag);
}
BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag);
- ts->particle.paintcursor = NULL;
- ts->particle.scene = NULL;
- ts->particle.object = NULL;
+ ts->particle.paintcursor = nullptr;
+ ts->particle.scene = nullptr;
+ ts->particle.object = nullptr;
/* duplicate Grease Pencil interpolation curve */
ts->gp_interpolate.custom_ipo = BKE_curvemapping_copy(ts->gp_interpolate.custom_ipo);
@@ -1743,7 +1741,7 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
void BKE_toolsettings_free(ToolSettings *toolsettings)
{
- if (toolsettings == NULL) {
+ if (toolsettings == nullptr) {
return;
}
if (toolsettings->vpaint) {
@@ -1811,7 +1809,7 @@ void BKE_scene_copy_data_eevee(Scene *sce_dst, const Scene *sce_src)
{
/* Copy eevee data between scenes. */
sce_dst->eevee = sce_src->eevee;
- sce_dst->eevee.light_cache_data = NULL;
+ sce_dst->eevee.light_cache_data = nullptr;
sce_dst->eevee.light_cache_info[0] = '\0';
/* TODO: Copy the cache. */
}
@@ -1862,7 +1860,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
/* make a private copy of the avicodecdata */
if (sce->r.avicodecdata) {
- sce_copy->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+ sce_copy->r.avicodecdata = static_cast<AviCodecData *>(MEM_dupallocN(sce->r.avicodecdata));
sce_copy->r.avicodecdata->lpFormat = MEM_dupallocN(sce_copy->r.avicodecdata->lpFormat);
sce_copy->r.avicodecdata->lpParms = MEM_dupallocN(sce_copy->r.avicodecdata->lpParms);
}
@@ -1870,14 +1868,14 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
BKE_sound_reset_scene_runtime(sce_copy);
/* grease pencil */
- sce_copy->gpd = NULL;
+ sce_copy->gpd = nullptr;
- sce_copy->preview = NULL;
+ sce_copy->preview = nullptr;
return sce_copy;
}
- eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
+ eDupli_ID_Flags duplicate_flags = (eDupli_ID_Flags)(U.dupflag | USER_DUP_OBJECT);
sce_copy = (Scene *)BKE_id_copy(bmain, (ID *)sce);
id_us_min(&sce_copy->id);
@@ -1900,7 +1898,7 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
/* 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;
+ duplicate_flags = (eDupli_ID_Flags)(duplicate_flags | USER_DUP_LINKED_ID);
}
}
@@ -1919,22 +1917,25 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
/* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
* duplicate along the object itself). */
- BKE_collection_duplicate(
- bmain, NULL, sce_copy->master_collection, duplicate_flags, LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ BKE_collection_duplicate(bmain,
+ nullptr,
+ sce_copy->master_collection,
+ duplicate_flags,
+ LIB_ID_DUPLICATE_IS_SUBPROCESS);
/* Rigid body world collections may not be instantiated as scene's collections, ensure they
* also get properly duplicated. */
- if (sce_copy->rigidbody_world != NULL) {
- if (sce_copy->rigidbody_world->group != NULL) {
+ if (sce_copy->rigidbody_world != nullptr) {
+ if (sce_copy->rigidbody_world->group != nullptr) {
BKE_collection_duplicate(bmain,
- NULL,
+ nullptr,
sce_copy->rigidbody_world->group,
duplicate_flags,
LIB_ID_DUPLICATE_IS_SUBPROCESS);
}
- if (sce_copy->rigidbody_world->constraints != NULL) {
+ if (sce_copy->rigidbody_world->constraints != nullptr) {
BKE_collection_duplicate(bmain,
- NULL,
+ nullptr,
sce_copy->rigidbody_world->constraints,
duplicate_flags,
LIB_ID_DUPLICATE_IS_SUBPROCESS);
@@ -1995,9 +1996,7 @@ bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
Scene *BKE_scene_add(Main *bmain, const char *name)
{
- Scene *sce;
-
- sce = BKE_id_new(bmain, ID_SCE, name);
+ Scene *sce = static_cast<Scene *>(BKE_id_new(bmain, ID_SCE, name));
id_us_min(&sce->id);
id_us_ensure_real(&sce->id);
@@ -2023,25 +2022,22 @@ Object *BKE_scene_object_find_by_name(const Scene *scene, const char *name)
}
}
}
- return NULL;
+ return nullptr;
}
void BKE_scene_set_background(Main *bmain, Scene *scene)
{
- Object *ob;
-
/* check for cyclic sets, for reading old files but also for definite security (py?) */
BKE_scene_validate_setscene(bmain, scene);
/* deselect objects (for dataselect) */
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
ob->flag &= ~SELECT;
}
/* copy layers and flags from bases to objects */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
- ob = base->object;
/* collection patch... */
BKE_scene_object_base_flag_sync_from_base(base);
}
@@ -2060,7 +2056,7 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
}
printf("Can't find scene: '%s' in file: '%s'\n", name, BKE_main_blendfile_path(bmain));
- return NULL;
+ return nullptr;
}
int BKE_scene_base_iter_next(
@@ -2071,9 +2067,9 @@ int BKE_scene_base_iter_next(
/* init */
if (val == 0) {
iter->phase = F_START;
- iter->dupob = NULL;
- iter->duplilist = NULL;
- iter->dupli_refob = NULL;
+ iter->dupob = nullptr;
+ iter->duplilist = nullptr;
+ iter->dupli_refob = nullptr;
}
else {
/* run_again is set when a duplilist has been ended */
@@ -2084,7 +2080,7 @@ int BKE_scene_base_iter_next(
if (iter->phase == F_START) {
ViewLayer *view_layer = (depsgraph) ? DEG_get_evaluated_view_layer(depsgraph) :
BKE_view_layer_context_active_PLACEHOLDER(*scene);
- *base = view_layer->object_bases.first;
+ *base = static_cast<Base *>(view_layer->object_bases.first);
if (*base) {
*ob = (*base)->object;
iter->phase = F_SCENE;
@@ -2095,7 +2091,7 @@ int BKE_scene_base_iter_next(
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
if (view_layer_set->object_bases.first) {
- *base = view_layer_set->object_bases.first;
+ *base = static_cast<Base *>(view_layer_set->object_bases.first);
*ob = (*base)->object;
iter->phase = F_SCENE;
break;
@@ -2116,7 +2112,7 @@ int BKE_scene_base_iter_next(
(*scene) = (*scene)->set;
ViewLayer *view_layer_set = BKE_view_layer_default_render(*scene);
if (view_layer_set->object_bases.first) {
- *base = view_layer_set->object_bases.first;
+ *base = static_cast<Base *>(view_layer_set->object_bases.first);
*ob = (*base)->object;
break;
}
@@ -2126,7 +2122,7 @@ int BKE_scene_base_iter_next(
}
}
- if (*base == NULL) {
+ if (*base == nullptr) {
iter->phase = F_START;
}
else {
@@ -2135,16 +2131,16 @@ int BKE_scene_base_iter_next(
/* Collections cannot be duplicated for meta-balls yet,
* this enters eternal loop because of
* makeDispListMBall getting called inside of collection_duplilist */
- if ((*base)->object->instance_collection == NULL) {
+ if ((*base)->object->instance_collection == nullptr) {
iter->duplilist = object_duplilist(depsgraph, (*scene), (*base)->object);
- iter->dupob = iter->duplilist->first;
+ iter->dupob = static_cast<DupliObject *>(iter->duplilist->first);
if (!iter->dupob) {
free_object_duplilist(iter->duplilist);
- iter->duplilist = NULL;
+ iter->duplilist = nullptr;
}
- iter->dupli_refob = NULL;
+ iter->dupli_refob = nullptr;
}
}
}
@@ -2174,11 +2170,11 @@ int BKE_scene_base_iter_next(
if (iter->dupli_refob) {
/* Restore last object's real matrix. */
copy_m4_m4(iter->dupli_refob->obmat, iter->omat);
- iter->dupli_refob = NULL;
+ iter->dupli_refob = nullptr;
}
free_object_duplilist(iter->duplilist);
- iter->duplilist = NULL;
+ iter->duplilist = nullptr;
run_again = true;
}
}
@@ -2195,7 +2191,7 @@ bool BKE_scene_has_view_layer(const Scene *scene, const ViewLayer *layer)
Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *collection)
{
- for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, layer, &scene->view_layers) {
if (BKE_view_layer_has_collection(layer, collection)) {
return scene;
@@ -2203,21 +2199,21 @@ Scene *BKE_scene_find_from_collection(const Main *bmain, const Collection *colle
}
}
- return NULL;
+ return nullptr;
}
#ifdef DURIAN_CAMERA_SWITCH
Object *BKE_scene_camera_switch_find(Scene *scene)
{
if (scene->r.mode & R_NO_CAMERA_SWITCH) {
- return NULL;
+ return nullptr;
}
const int ctime = (int)BKE_scene_ctime_get(scene);
int frame = -(MAXFRAME + 1);
int min_frame = MAXFRAME + 1;
- Object *camera = NULL;
- Object *first_camera = NULL;
+ Object *camera = nullptr;
+ Object *first_camera = nullptr;
LISTBASE_FOREACH (TimeMarker *, m, &scene->markers) {
if (m->camera && (m->camera->visibility_flag & OB_HIDE_RENDER) == 0) {
@@ -2237,7 +2233,7 @@ Object *BKE_scene_camera_switch_find(Scene *scene)
}
}
- if (camera == NULL) {
+ if (camera == nullptr) {
/* If there's no marker to the left of current frame,
* use camera from left-most marker to solve all sort
* of Schrodinger uncertainties.
@@ -2270,7 +2266,10 @@ const char *BKE_scene_find_marker_name(const Scene *scene, int frame)
const TimeMarker *m1, *m2;
/* search through markers for match */
- for (m1 = markers->first, m2 = markers->last; m1 && m2; m1 = m1->next, m2 = m2->prev) {
+ for (m1 = static_cast<const TimeMarker *>(markers->first),
+ m2 = static_cast<const TimeMarker *>(markers->last);
+ m1 && m2;
+ m1 = m1->next, m2 = m2->prev) {
if (m1->frame == frame) {
return m1->name;
}
@@ -2284,14 +2283,14 @@ const char *BKE_scene_find_marker_name(const Scene *scene, int frame)
}
}
- return NULL;
+ return nullptr;
}
const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame)
{
- const TimeMarker *marker, *best_marker = NULL;
+ const TimeMarker *best_marker = nullptr;
int best_frame = -MAXFRAME * 2;
- for (marker = scene->markers.first; marker; marker = marker->next) {
+ LISTBASE_FOREACH (const TimeMarker *, marker, &scene->markers) {
if (marker->frame == frame) {
return marker->name;
}
@@ -2302,7 +2301,7 @@ const char *BKE_scene_find_last_marker_name(const Scene *scene, int frame)
}
}
- return best_marker ? best_marker->name : NULL;
+ return best_marker ? best_marker->name : nullptr;
}
int BKE_scene_frame_snap_by_seconds(Scene *scene, double interval_in_seconds, int frame)
@@ -2335,7 +2334,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
Scene *sce_iter;
int a, totscene;
- if (sce->set == NULL) {
+ if (sce->set == nullptr) {
return true;
}
totscene = BLI_listbase_count(&bmain->scenes);
@@ -2344,7 +2343,7 @@ bool BKE_scene_validate_setscene(Main *bmain, Scene *sce)
/* more iterations than scenes means we have a cycle */
if (a > totscene) {
/* the tested scene gets zero'ed, that's typically current scene */
- sce->set = NULL;
+ sce->set = nullptr;
return false;
}
}
@@ -2437,9 +2436,8 @@ int BKE_scene_orientation_get_index_from_flag(Scene *scene, int flag)
static bool check_rendered_viewport_visible(Main *bmain)
{
- wmWindowManager *wm = bmain->wm.first;
- wmWindow *window;
- for (window = wm->windows.first; window != NULL; window = window->next) {
+ wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first);
+ LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) {
const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook);
Scene *scene = window->scene;
RenderEngineType *type = RE_engines_find(scene->r.engine);
@@ -2448,8 +2446,8 @@ static bool check_rendered_viewport_visible(Main *bmain)
continue;
}
- for (ScrArea *area = screen->areabase.first; area != NULL; area = area->next) {
- View3D *v3d = area->spacedata.first;
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ View3D *v3d = static_cast<View3D *>(area->spacedata.first);
if (area->spacetype != SPACE_VIEW3D) {
continue;
}
@@ -2462,7 +2460,7 @@ static bool check_rendered_viewport_visible(Main *bmain)
}
/* TODO(campbell): shouldn't we be able to use 'DEG_get_view_layer' here?
- * Currently this is NULL on load, so don't. */
+ * Currently this is nullptr on load, so don't. */
static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_layer)
{
/* This is needed to prepare mesh to be used by the render
@@ -2476,18 +2474,15 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
Object *obedit = OBEDIT_FROM_VIEW_LAYER(view_layer);
if (obedit) {
- Mesh *mesh = obedit->data;
+ Mesh *mesh = static_cast<Mesh *>(obedit->data);
if ((obedit->type == OB_MESH) &&
((obedit->id.recalc & ID_RECALC_ALL) || (mesh->id.recalc & ID_RECALC_ALL))) {
if (check_rendered_viewport_visible(bmain)) {
BMesh *bm = mesh->edit_mesh->bm;
- BM_mesh_bm_to_me(bmain,
- bm,
- mesh,
- (&(struct BMeshToMeshParams){
- .calc_object_remap = true,
- .update_shapekey_indices = true,
- }));
+ BMeshToMeshParams params{};
+ params.calc_object_remap = true;
+ params.update_shapekey_indices = true;
+ BM_mesh_bm_to_me(bmain, bm, mesh, &params);
DEG_id_tag_update(&mesh->id, 0);
}
}
@@ -2697,13 +2692,11 @@ void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, View
SceneRenderView *BKE_scene_add_render_view(Scene *sce, const char *name)
{
- SceneRenderView *srv;
-
if (!name) {
name = DATA_("RenderView");
}
- srv = MEM_callocN(sizeof(SceneRenderView), "new render view");
+ SceneRenderView *srv = MEM_cnew<SceneRenderView>(__func__);
BLI_strncpy(srv->name, name, sizeof(srv->name));
BLI_uniquename(&sce->r.views,
srv,
@@ -2751,17 +2744,17 @@ int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
return lvl;
}
-int get_render_child_particle_number(const RenderData *r, int num, bool for_render)
+int get_render_child_particle_number(const RenderData *r, int child_num, bool for_render)
{
if (r->mode & R_SIMPLIFY) {
if (for_render) {
- return (int)(r->simplify_particles_render * num);
+ return (int)(r->simplify_particles_render * child_num);
}
- return (int)(r->simplify_particles * num);
+ return (int)(r->simplify_particles * child_num);
}
- return num;
+ return child_num;
}
Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
@@ -2770,7 +2763,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
/* Common case, step to the next. */
return base->next;
}
- if ((base == NULL) && (view_layer != NULL)) {
+ if ((base == nullptr) && (view_layer != nullptr)) {
/* First time looping, return the scenes first base. */
/* For the first loop we should get the layer from workspace when available. */
if (view_layer->object_bases.first) {
@@ -2792,7 +2785,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
}
}
- return NULL;
+ return nullptr;
}
bool BKE_scene_use_shading_nodes_custom(Scene *scene)
@@ -2823,10 +2816,10 @@ bool BKE_scene_uses_cycles(const Scene *scene)
}
/* This enumeration has to match the one defined in the Cycles addon. */
-typedef enum eCyclesFeatureSet {
+enum eCyclesFeatureSet {
CYCLES_FEATURES_SUPPORTED = 0,
CYCLES_FEATURES_EXPERIMENTAL = 1,
-} eCyclesFeatureSet;
+};
bool BKE_scene_uses_cycles_experimental_features(Scene *scene)
{
@@ -2845,7 +2838,7 @@ bool BKE_scene_uses_cycles_experimental_features(Scene *scene)
void BKE_scene_base_flag_to_objects(ViewLayer *view_layer)
{
- Base *base = view_layer->object_bases.first;
+ Base *base = static_cast<Base *>(view_layer->object_bases.first);
while (base) {
BKE_scene_object_base_flag_sync_from_base(base);
@@ -2954,7 +2947,6 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl
int BKE_scene_multiview_num_views_get(const RenderData *rd)
{
- SceneRenderView *srv;
int totviews = 0;
if ((rd->scemode & R_MULTIVIEW) == 0) {
@@ -2962,18 +2954,20 @@ int BKE_scene_multiview_num_views_get(const RenderData *rd)
}
if (rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
- srv = BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name));
+ SceneRenderView *srv = static_cast<SceneRenderView *>(
+ BLI_findstring(&rd->views, STEREO_LEFT_NAME, offsetof(SceneRenderView, name)));
if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
totviews++;
}
- srv = BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name));
+ srv = static_cast<SceneRenderView *>(
+ BLI_findstring(&rd->views, STEREO_RIGHT_NAME, offsetof(SceneRenderView, name)));
if ((srv && srv->viewflag & SCE_VIEW_DISABLE) == 0) {
totviews++;
}
}
else {
- for (srv = rd->views.first; srv; srv = srv->next) {
+ LISTBASE_FOREACH (SceneRenderView *, srv, &rd->views) {
if ((srv->viewflag & SCE_VIEW_DISABLE) == 0) {
totviews++;
}
@@ -3001,7 +2995,7 @@ bool BKE_scene_multiview_is_stereo3d(const RenderData *rd)
bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const SceneRenderView *srv)
{
- if (srv == NULL) {
+ if (srv == nullptr) {
return false;
}
@@ -3027,8 +3021,6 @@ bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const Scene
bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *viewname)
{
- SceneRenderView *srv;
-
if ((rd->scemode & R_MULTIVIEW) == 0) {
return true;
}
@@ -3037,7 +3029,7 @@ bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *
return true;
}
- for (srv = rd->views.first; srv; srv = srv->next) {
+ LISTBASE_FOREACH (const SceneRenderView *, srv, &rd->views) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
return STREQ(viewname, srv->name);
}
@@ -3048,8 +3040,6 @@ bool BKE_scene_multiview_is_render_view_first(const RenderData *rd, const char *
bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *viewname)
{
- SceneRenderView *srv;
-
if ((rd->scemode & R_MULTIVIEW) == 0) {
return true;
}
@@ -3058,7 +3048,7 @@ bool BKE_scene_multiview_is_render_view_last(const RenderData *rd, const char *v
return true;
}
- for (srv = rd->views.last; srv; srv = srv->prev) {
+ LISTBASE_FOREACH_BACKWARD (const SceneRenderView *, srv, &rd->views) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
return STREQ(viewname, srv->name);
}
@@ -3073,10 +3063,10 @@ SceneRenderView *BKE_scene_multiview_render_view_findindex(const RenderData *rd,
size_t nr;
if ((rd->scemode & R_MULTIVIEW) == 0) {
- return NULL;
+ return nullptr;
}
- for (srv = rd->views.first, nr = 0; srv; srv = srv->next) {
+ for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
if (nr++ == view_id) {
return srv;
@@ -3110,7 +3100,7 @@ int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
return 0;
}
- for (srv = rd->views.first, nr = 0; srv; srv = srv->next) {
+ for (srv = static_cast<SceneRenderView *>(rd->views.first), nr = 0; srv; srv = srv->next) {
if (BKE_scene_multiview_is_render_view_active(rd, srv)) {
if (STREQ(viewname, srv->name)) {
return nr;
@@ -3139,7 +3129,8 @@ void BKE_scene_multiview_view_filepath_get(const RenderData *rd,
SceneRenderView *srv;
char suffix[FILE_MAX];
- srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name));
+ srv = static_cast<SceneRenderView *>(
+ BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
if (srv) {
BLI_strncpy(suffix, srv->suffix, sizeof(suffix));
}
@@ -3155,11 +3146,12 @@ const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char
{
SceneRenderView *srv;
- if ((viewname == NULL) || (viewname[0] == '\0')) {
+ if ((viewname == nullptr) || (viewname[0] == '\0')) {
return viewname;
}
- srv = BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name));
+ srv = static_cast<SceneRenderView *>(
+ BLI_findstring(&rd->views, viewname, offsetof(SceneRenderView, name)));
if (srv) {
return srv->suffix;
}
@@ -3182,7 +3174,6 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene,
char *r_prefix,
const char **r_ext)
{
- SceneRenderView *srv;
size_t index_act;
const char *suf_act;
const char delims[] = {'.', '\0'};
@@ -3191,13 +3182,13 @@ void BKE_scene_multiview_view_prefix_get(Scene *scene,
/* begin of extension */
index_act = BLI_str_rpartition(name, delims, r_ext, &suf_act);
- if (*r_ext == NULL) {
+ if (*r_ext == nullptr) {
return;
}
BLI_assert(index_act > 0);
UNUSED_VARS_NDEBUG(index_act);
- for (srv = scene->r.views.first; srv; srv = srv->next) {
+ LISTBASE_FOREACH (SceneRenderView *, srv, &scene->r.views) {
if (BKE_scene_multiview_is_render_view_active(&scene->r, srv)) {
const size_t len = strlen(srv->suffix);
const size_t ext_len = strlen(*r_ext);
@@ -3250,16 +3241,16 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd)
/* Manipulation of depsgraph storage. */
/* This is a key which identifies depsgraph. */
-typedef struct DepsgraphKey {
+struct DepsgraphKey {
const ViewLayer *view_layer;
/* TODO(sergey): Need to include window somehow (same layer might be in a
* different states in different windows).
*/
-} DepsgraphKey;
+};
static unsigned int depsgraph_key_hash(const void *key_v)
{
- const DepsgraphKey *key = key_v;
+ const DepsgraphKey *key = static_cast<const DepsgraphKey *>(key_v);
unsigned int hash = BLI_ghashutil_ptrhash(key->view_layer);
/* TODO(sergey): Include hash from other fields in the key. */
return hash;
@@ -3267,21 +3258,21 @@ static unsigned int depsgraph_key_hash(const void *key_v)
static bool depsgraph_key_compare(const void *key_a_v, const void *key_b_v)
{
- const DepsgraphKey *key_a = key_a_v;
- const DepsgraphKey *key_b = key_b_v;
+ const DepsgraphKey *key_a = static_cast<const DepsgraphKey *>(key_a_v);
+ const DepsgraphKey *key_b = static_cast<const DepsgraphKey *>(key_b_v);
/* TODO(sergey): Compare rest of. */
return !(key_a->view_layer == key_b->view_layer);
}
static void depsgraph_key_free(void *key_v)
{
- DepsgraphKey *key = key_v;
+ DepsgraphKey *key = static_cast<DepsgraphKey *>(key_v);
MEM_freeN(key);
}
static void depsgraph_key_value_free(void *value)
{
- Depsgraph *depsgraph = value;
+ Depsgraph *depsgraph = static_cast<Depsgraph *>(value);
DEG_graph_free(depsgraph);
}
@@ -3293,23 +3284,23 @@ void BKE_scene_allocate_depsgraph_hash(Scene *scene)
void BKE_scene_ensure_depsgraph_hash(Scene *scene)
{
- if (scene->depsgraph_hash == NULL) {
+ if (scene->depsgraph_hash == nullptr) {
BKE_scene_allocate_depsgraph_hash(scene);
}
}
void BKE_scene_free_depsgraph_hash(Scene *scene)
{
- if (scene->depsgraph_hash == NULL) {
+ if (scene->depsgraph_hash == nullptr) {
return;
}
BLI_ghash_free(scene->depsgraph_hash, depsgraph_key_free, depsgraph_key_value_free);
- scene->depsgraph_hash = NULL;
+ scene->depsgraph_hash = nullptr;
}
void BKE_scene_free_view_layer_depsgraph(Scene *scene, ViewLayer *view_layer)
{
- if (scene->depsgraph_hash != NULL) {
+ if (scene->depsgraph_hash != nullptr) {
DepsgraphKey key = {view_layer};
BLI_ghash_remove(scene->depsgraph_hash, &key, depsgraph_key_free, depsgraph_key_value_free);
}
@@ -3321,17 +3312,17 @@ static Depsgraph **scene_get_depsgraph_p(Scene *scene,
ViewLayer *view_layer,
const bool allocate_ghash_entry)
{
- /* bmain may be NULL here! */
- BLI_assert(scene != NULL);
- BLI_assert(view_layer != NULL);
+ /* bmain may be nullptr here! */
+ BLI_assert(scene != nullptr);
+ BLI_assert(view_layer != nullptr);
BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
/* Make sure hash itself exists. */
if (allocate_ghash_entry) {
BKE_scene_ensure_depsgraph_hash(scene);
}
- if (scene->depsgraph_hash == NULL) {
- return NULL;
+ if (scene->depsgraph_hash == nullptr) {
+ return nullptr;
}
DepsgraphKey key;
@@ -3350,23 +3341,23 @@ static Depsgraph **scene_get_depsgraph_p(Scene *scene,
}
/* Depsgraph was not found in the ghash, but the key still needs allocating. */
- *key_ptr = MEM_mallocN(sizeof(DepsgraphKey), __func__);
+ *key_ptr = MEM_new<DepsgraphKey>(__func__);
**key_ptr = key;
- *depsgraph_ptr = NULL;
+ *depsgraph_ptr = nullptr;
return depsgraph_ptr;
}
static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer *view_layer)
{
- BLI_assert(bmain != NULL);
+ BLI_assert(bmain != nullptr);
Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, true);
- if (depsgraph_ptr == NULL) {
+ if (depsgraph_ptr == nullptr) {
/* The scene has no depsgraph hash. */
- return NULL;
+ return nullptr;
}
- if (*depsgraph_ptr != NULL) {
+ if (*depsgraph_ptr != nullptr) {
/* The depsgraph was found, no need to allocate. */
return depsgraph_ptr;
}
@@ -3393,25 +3384,25 @@ Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_lay
{
BLI_assert(BKE_scene_has_view_layer(scene, view_layer));
- if (scene->depsgraph_hash == NULL) {
- return NULL;
+ if (scene->depsgraph_hash == nullptr) {
+ return nullptr;
}
DepsgraphKey key;
key.view_layer = view_layer;
- return BLI_ghash_lookup(scene->depsgraph_hash, &key);
+ return static_cast<Depsgraph *>(BLI_ghash_lookup(scene->depsgraph_hash, &key));
}
Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
{
Depsgraph **depsgraph_ptr = scene_ensure_depsgraph_p(bmain, scene, view_layer);
- return (depsgraph_ptr != NULL) ? *depsgraph_ptr : NULL;
+ return (depsgraph_ptr != nullptr) ? *depsgraph_ptr : nullptr;
}
static char *scene_undo_depsgraph_gen_key(Scene *scene, ViewLayer *view_layer, char *key_full)
{
- if (key_full == NULL) {
- key_full = MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__);
+ if (key_full == nullptr) {
+ key_full = static_cast<char *>(MEM_callocN(MAX_ID_NAME + FILE_MAX + MAX_NAME, __func__));
}
size_t key_full_offset = BLI_strncpy_rlen(key_full, scene->id.name, MAX_ID_NAME);
@@ -3430,24 +3421,23 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain)
GHash *depsgraph_extract = BLI_ghash_new(
BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
- for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
- if (scene->depsgraph_hash == NULL) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ if (scene->depsgraph_hash == nullptr) {
/* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will
- * be built so this pointer may be NULL. */
+ * be built so this pointer may be nullptr. */
continue;
}
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
- view_layer = view_layer->next) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
DepsgraphKey key;
key.view_layer = view_layer;
Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key);
- if (depsgraph != NULL && *depsgraph != NULL) {
- char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, NULL);
+ if (depsgraph != nullptr && *depsgraph != nullptr) {
+ char *key_full = scene_undo_depsgraph_gen_key(scene, view_layer, nullptr);
/* We steal the depsgraph from the scene. */
BLI_ghash_insert(depsgraph_extract, key_full, *depsgraph);
- *depsgraph = NULL;
+ *depsgraph = nullptr;
}
}
}
@@ -3457,22 +3447,21 @@ GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain)
void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
{
- for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
- for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL;
- view_layer = view_layer->next) {
+ LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
+ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
char key_full[MAX_ID_NAME + FILE_MAX + MAX_NAME] = {0};
scene_undo_depsgraph_gen_key(scene, view_layer, key_full);
Depsgraph **depsgraph_extract_ptr = (Depsgraph **)BLI_ghash_lookup_p(depsgraph_extract,
key_full);
- if (depsgraph_extract_ptr == NULL) {
+ if (depsgraph_extract_ptr == nullptr) {
continue;
}
- BLI_assert(*depsgraph_extract_ptr != NULL);
+ BLI_assert(*depsgraph_extract_ptr != nullptr);
Depsgraph **depsgraph_scene_ptr = scene_get_depsgraph_p(scene, view_layer, true);
- BLI_assert(depsgraph_scene_ptr != NULL);
- BLI_assert(*depsgraph_scene_ptr == NULL);
+ BLI_assert(depsgraph_scene_ptr != nullptr);
+ BLI_assert(*depsgraph_scene_ptr == nullptr);
/* We steal the depsgraph back from our 'extract' storage to the scene. */
Depsgraph *depsgraph = *depsgraph_extract_ptr;
@@ -3482,7 +3471,7 @@ void BKE_scene_undo_depsgraphs_restore(Main *bmain, GHash *depsgraph_extract)
DEG_graph_tag_relations_update(depsgraph);
*depsgraph_scene_ptr = depsgraph;
- *depsgraph_extract_ptr = NULL;
+ *depsgraph_extract_ptr = nullptr;
}
}
@@ -3515,7 +3504,7 @@ void BKE_scene_transform_orientation_remove(Scene *scene, TransformOrientation *
TransformOrientation *BKE_scene_transform_orientation_find(const Scene *scene, const int index)
{
- return BLI_findlink(&scene->transform_spaces, index);
+ return static_cast<TransformOrientation *>(BLI_findlink(&scene->transform_spaces, index));
}
int BKE_scene_transform_orientation_get_index(const Scene *scene,
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 7d0c6598440..f17450ac3f4 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -1166,18 +1166,18 @@ static void studiolight_add_files_from_datafolder(const int folder_id,
const char *subfolder,
int flag)
{
- struct direntry *dir;
+ struct direntry *dirs;
const char *folder = BKE_appdir_folder_id(folder_id, subfolder);
if (folder) {
- uint totfile = BLI_filelist_dir_contents(folder, &dir);
+ const uint dirs_num = BLI_filelist_dir_contents(folder, &dirs);
int i;
- for (i = 0; i < totfile; i++) {
- if (dir[i].type & S_IFREG) {
- studiolight_add_file(dir[i].path, flag);
+ for (i = 0; i < dirs_num; i++) {
+ if (dirs[i].type & S_IFREG) {
+ studiolight_add_file(dirs[i].path, flag);
}
}
- BLI_filelist_free(dir, totfile);
- dir = NULL;
+ BLI_filelist_free(dirs, dirs_num);
+ dirs = NULL;
}
}
diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.c
index 7b1ebd5df1f..ee1976d5946 100644
--- a/source/blender/blenkernel/intern/subdiv.c
+++ b/source/blender/blenkernel/intern/subdiv.c
@@ -106,7 +106,7 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings,
* The thing here is: OpenSubdiv can only deal with faces, but our
* side of subdiv also deals with loose vertices and edges. */
}
- Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converetr");
+ Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converter");
subdiv->settings = *settings;
subdiv->topology_refiner = osd_topology_refiner;
subdiv->evaluator = NULL;
diff --git a/source/blender/blenlib/BLI_enumerable_thread_specific.hh b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
index 51bf8d06cf1..a5bd79d5826 100644
--- a/source/blender/blenlib/BLI_enumerable_thread_specific.hh
+++ b/source/blender/blenlib/BLI_enumerable_thread_specific.hh
@@ -3,23 +3,20 @@
#pragma once
#ifdef WITH_TBB
-
-# ifdef WITH_TBB
/* Quiet top level deprecation message, unrelated to API usage here. */
-# if defined(WIN32) && !defined(NOMINMAX)
+# if defined(WIN32) && !defined(NOMINMAX)
/* TBB includes Windows.h which will define min/max macros causing issues
* when we try to use std::min and std::max later on. */
-# define NOMINMAX
-# define TBB_MIN_MAX_CLEANUP
-# endif
-# include <tbb/enumerable_thread_specific.h>
-# ifdef WIN32
+# define NOMINMAX
+# define TBB_MIN_MAX_CLEANUP
+# endif
+# include <tbb/enumerable_thread_specific.h>
+# ifdef WIN32
/* We cannot keep this defined, since other parts of the code deal with this on their own, leading
* to multiple define warnings unless we un-define this, however we can only undefine this if we
* were the ones that made the definition earlier. */
-# ifdef TBB_MIN_MAX_CLEANUP
-# undef NOMINMAX
-# endif
+# ifdef TBB_MIN_MAX_CLEANUP
+# undef NOMINMAX
# endif
# endif
#endif
diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh
index 6a988eda8a9..83f414f853a 100644
--- a/source/blender/blenlib/BLI_math_base.hh
+++ b/source/blender/blenlib/BLI_math_base.hh
@@ -12,7 +12,6 @@
#include <type_traits>
#include "BLI_math_base_safe.h"
-#include "BLI_math_vec_types.hh"
#include "BLI_utildefines.h"
#ifdef WITH_GMP
@@ -21,6 +20,15 @@
namespace blender::math {
+template<typename T>
+inline constexpr bool is_math_float_type = (std::is_floating_point_v<T>
+#ifdef WITH_GMP
+ || std::is_same_v<T, mpq_class>
+#endif
+);
+
+template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>;
+
template<typename T> inline bool is_zero(const T &a)
{
return a == T(0);
@@ -84,19 +92,23 @@ template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T ceil(const
return std::ceil(a);
}
+template<typename T> inline T distance(const T &a, const T &b)
+{
+ return std::abs(a - b);
+}
+
template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(const T &a)
{
return a - std::floor(a);
}
-template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
-inline T interpolate(const T &a, const T &b, const T &t)
+template<typename T, typename FactorT, BLI_ENABLE_IF((is_math_float_type<FactorT>))>
+inline T interpolate(const T &a, const T &b, const FactorT &t)
{
return a * (1 - t) + b * t;
}
-template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))>
-inline T midpoint(const T &a, const T &b)
+template<typename T> inline T midpoint(const T &a, const T &b)
{
return (a + b) * T(0.5);
}
diff --git a/source/blender/blenlib/BLI_math_statistics.h b/source/blender/blenlib/BLI_math_statistics.h
index d33d4be360a..501a250e1a0 100644
--- a/source/blender/blenlib/BLI_math_statistics.h
+++ b/source/blender/blenlib/BLI_math_statistics.h
@@ -28,7 +28,7 @@ extern "C" {
*
* \param n: the dimension of the vectors (and hence, of the covariance matrix to compute).
* \param cos_vn: the nD points to compute covariance from.
- * \param nbr_cos_vn: the number of nD coordinates in cos_vn.
+ * \param cos_vn_num: the number of nD coordinates in cos_vn.
* \param center: the center (or mean point) of cos_vn. If NULL,
* it is assumed cos_vn is already centered.
* \param use_sample_correction: whether to apply sample correction
@@ -37,7 +37,7 @@ extern "C" {
*/
void BLI_covariance_m_vn_ex(int n,
const float *cos_vn,
- int nbr_cos_vn,
+ int cos_vn_num,
const float *center,
bool use_sample_correction,
float *r_covmat);
@@ -45,12 +45,12 @@ void BLI_covariance_m_vn_ex(int n,
* \brief Compute the covariance matrix of given set of 3D coordinates.
*
* \param cos_v3: the 3D points to compute covariance from.
- * \param nbr_cos_v3: the number of 3D coordinates in cos_v3.
+ * \param cos_v3_num: the number of 3D coordinates in cos_v3.
* \return r_covmat the computed covariance matrix.
* \return r_center the computed center (mean) of 3D points (may be NULL).
*/
void BLI_covariance_m3_v3n(const float (*cos_v3)[3],
- int nbr_cos_v3,
+ int cos_v3_num,
bool use_sample_correction,
float r_covmat[3][3],
float r_center[3]);
diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh
index 389307e331d..d9524eae746 100644
--- a/source/blender/blenlib/BLI_math_vec_types.hh
+++ b/source/blender/blenlib/BLI_math_vec_types.hh
@@ -321,7 +321,7 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size>
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b[i]);
}
- friend vec_base operator*(const vec_base &a, T b)
+ template<typename FactorT> friend vec_base operator*(const vec_base &a, FactorT b)
{
BLI_VEC_OP_IMPL(ret, i, ret[i] = a[i] * b);
}
@@ -579,13 +579,4 @@ using double2 = vec_base<double, 2>;
using double3 = vec_base<double, 3>;
using double4 = vec_base<double, 4>;
-template<typename T>
-inline constexpr bool is_math_float_type = (std::is_floating_point_v<T>
-#ifdef WITH_GMP
- || std::is_same_v<T, mpq_class>
-#endif
-);
-
-template<typename T> inline constexpr bool is_math_integral_type = std::is_integral_v<T>;
-
} // namespace blender
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 4689072bcce..f3283371a3c 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -389,7 +389,7 @@ void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float
void mid_v2_v2v2v2(float v[2], const float v1[2], const float v2[2], const float v3[2]);
void mid_v3_v3v3v3v3(
float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
-void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], unsigned int nbr);
+void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], unsigned int vec_arr_num);
/**
* Specialized function for calculating normals.
@@ -660,7 +660,10 @@ void minmax_v4v4_v4(float min[4], float max[4], const float vec[4]);
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3]);
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2]);
-void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr);
+void minmax_v3v3_v3_array(float r_min[3],
+ float r_max[3],
+ const float (*vec_arr)[3],
+ int var_arr_num);
/** ensure \a v1 is \a dist from \a v2 */
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], float dist);
diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh
index b1a3242ae52..b9f0939674e 100644
--- a/source/blender/blenlib/BLI_math_vector.hh
+++ b/source/blender/blenlib/BLI_math_vector.hh
@@ -10,7 +10,7 @@
#include <cmath>
#include <type_traits>
-#include "BLI_math_base_safe.h"
+#include "BLI_math_base.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_span.hh"
#include "BLI_utildefines.h"
@@ -339,10 +339,10 @@ inline vec_base<T, 3> cross_poly(Span<vec_base<T, 3>> poly)
return n;
}
-template<typename T, int Size, BLI_ENABLE_IF((is_math_float_type<T>))>
+template<typename T, typename FactorT, int Size, BLI_ENABLE_IF((is_math_float_type<FactorT>))>
inline vec_base<T, Size> interpolate(const vec_base<T, Size> &a,
const vec_base<T, Size> &b,
- const T &t)
+ const FactorT &t)
{
return a * (1 - t) + b * t;
}
diff --git a/source/blender/blenlib/BLI_timeit.hh b/source/blender/blenlib/BLI_timeit.hh
index 31e1b5d2a03..8da0a020d99 100644
--- a/source/blender/blenlib/BLI_timeit.hh
+++ b/source/blender/blenlib/BLI_timeit.hh
@@ -38,6 +38,41 @@ class ScopedTimer {
}
};
+class ScopedTimerAveraged {
+ private:
+ std::string name_;
+ TimePoint start_;
+
+ int64_t &total_count_;
+ Nanoseconds &total_time_;
+ Nanoseconds &min_time_;
+
+ public:
+ ScopedTimerAveraged(std::string name,
+ int64_t &total_count,
+ Nanoseconds &total_time,
+ Nanoseconds &min_time)
+ : name_(std::move(name)),
+ total_count_(total_count),
+ total_time_(total_time),
+ min_time_(min_time)
+ {
+ start_ = Clock::now();
+ }
+
+ ~ScopedTimerAveraged();
+};
+
} // namespace blender::timeit
#define SCOPED_TIMER(name) blender::timeit::ScopedTimer scoped_timer(name)
+
+/**
+ * Print the average and minimum runtime of the timer's scope.
+ * \warning This uses static variables, so it is not thread-safe.
+ */
+#define SCOPED_TIMER_AVERAGED(name) \
+ static int64_t total_count_; \
+ static blender::timeit::Nanoseconds total_time_; \
+ static blender::timeit::Nanoseconds min_time_ = blender::timeit::Nanoseconds::max(); \
+ blender::timeit::ScopedTimerAveraged scoped_timer(name, total_count_, total_time_, min_time_)
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index af71c96fc10..647726722b1 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -165,8 +165,8 @@ set(SRC
BLI_bitmap.h
BLI_bitmap_draw_2d.h
BLI_blenlib.h
- BLI_boxpack_2d.h
BLI_bounds.hh
+ BLI_boxpack_2d.h
BLI_buffer.h
BLI_color.hh
BLI_compiler_attrs.h
@@ -174,8 +174,8 @@ set(SRC
BLI_compiler_typecheck.h
BLI_console.h
BLI_convexhull_2d.h
- BLI_cpp_type_make.hh
BLI_cpp_type.hh
+ BLI_cpp_type_make.hh
BLI_delaunay_2d.h
BLI_dial_2d.h
BLI_disjoint_set.hh
@@ -235,8 +235,8 @@ set(SRC
BLI_map.hh
BLI_map_slots.hh
BLI_math.h
- BLI_math_base.hh
BLI_math_base.h
+ BLI_math_base.hh
BLI_math_base_safe.h
BLI_math_bits.h
BLI_math_boolean.hh
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index 9f1f8fe0448..76fc5b6342a 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -97,8 +97,8 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
}
struct BuildDirCtx {
- struct direntry *files; /* array[nrfiles] */
- int nrfiles;
+ struct direntry *files; /* array[files_num] */
+ int files_num;
};
/**
@@ -154,7 +154,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
if (newnum) {
if (dir_ctx->files) {
void *const tmp = MEM_reallocN(dir_ctx->files,
- (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
+ (dir_ctx->files_num + newnum) * sizeof(struct direntry));
if (tmp) {
dir_ctx->files = (struct direntry *)tmp;
}
@@ -171,7 +171,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
if (dir_ctx->files) {
struct dirlink *dlink = (struct dirlink *)dirbase.first;
- struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
+ struct direntry *file = &dir_ctx->files[dir_ctx->files_num];
while (dlink) {
char fullname[PATH_MAX];
memset(file, 0, sizeof(struct direntry));
@@ -186,7 +186,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
* does not support stat on '\\SERVER\foo\..', sigh... */
file->type |= S_IFDIR;
}
- dir_ctx->nrfiles++;
+ dir_ctx->files_num++;
file++;
dlink = dlink->next;
}
@@ -199,7 +199,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
BLI_freelist(&dirbase);
if (dir_ctx->files) {
qsort(dir_ctx->files,
- dir_ctx->nrfiles,
+ dir_ctx->files_num,
sizeof(struct direntry),
(int (*)(const void *, const void *))bli_compare);
}
@@ -219,7 +219,7 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_
{
struct BuildDirCtx dir_ctx;
- dir_ctx.nrfiles = 0;
+ dir_ctx.files_num = 0;
dir_ctx.files = NULL;
bli_builddir(&dir_ctx, dirname);
@@ -233,7 +233,7 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_
*r_filelist = MEM_mallocN(sizeof(**r_filelist), __func__);
}
- return dir_ctx.nrfiles;
+ return dir_ctx.files_num;
}
void BLI_filelist_entry_size_to_string(const struct stat *st,
diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc
index e6164c98402..3039b72128d 100644
--- a/source/blender/blenlib/intern/delaunay_2d.cc
+++ b/source/blender/blenlib/intern/delaunay_2d.cc
@@ -2188,17 +2188,19 @@ static int power_of_10_greater_equal_to(int x)
}
/**
- Incrementally each edge of each input face as an edge constraint.
+ * Incrementally each edge of each input face as an edge constraint.
* The code will ensure that the #CDTEdge's created will have ids that tie them
* back to the original face edge (using a numbering system for those edges
* that starts with cdt->face_edge_offset, and continues with the edges in
* order around each face in turn. And then the next face starts at
* cdt->face_edge_offset beyond the start for the previous face.
+ * Return the number of faces added, which may be less than input.face.size()
+ * in the case that some faces have less than 3 sides.
*/
template<typename T>
-void add_face_constraints(CDT_state<T> *cdt_state,
- const CDT_input<T> &input,
- CDT_output_type output_type)
+int add_face_constraints(CDT_state<T> *cdt_state,
+ const CDT_input<T> &input,
+ CDT_output_type output_type)
{
int nv = input.vert.size();
int nf = input.face.size();
@@ -2216,6 +2218,7 @@ void add_face_constraints(CDT_state<T> *cdt_state,
* together the are >= INT_MAX, then the Delaunay calculation will take unreasonably long anyway.
*/
BLI_assert(INT_MAX / cdt_state->face_edge_offset > nf);
+ int faces_added = 0;
for (int f = 0; f < nf; f++) {
int flen = input.face[f].size();
if (flen <= 2) {
@@ -2231,6 +2234,7 @@ void add_face_constraints(CDT_state<T> *cdt_state,
/* Ignore face edges with invalid vertices. */
continue;
}
+ ++faces_added;
CDTVert<T> *v1 = cdt->get_vert_resolve_merge(iv1);
CDTVert<T> *v2 = cdt->get_vert_resolve_merge(iv2);
LinkNode *edge_list;
@@ -2265,6 +2269,7 @@ void add_face_constraints(CDT_state<T> *cdt_state,
}
}
}
+ return faces_added;
}
/* Delete_edge but try not to mess up outer face.
@@ -2642,7 +2647,8 @@ CDT_result<T> get_cdt_output(CDT_state<T> *cdt_state,
const CDT_input<T> UNUSED(input),
CDT_output_type output_type)
{
- prepare_cdt_for_output(cdt_state, output_type);
+ CDT_output_type oty = output_type;
+ prepare_cdt_for_output(cdt_state, oty);
CDT_result<T> result;
CDTArrangement<T> *cdt = &cdt_state->cdt;
result.face_edge_offset = cdt_state->face_edge_offset;
@@ -2774,7 +2780,11 @@ CDT_result<T> delaunay_calc(const CDT_input<T> &input, CDT_output_type output_ty
add_input_verts(&cdt_state, input);
initial_triangulation(&cdt_state.cdt);
add_edge_constraints(&cdt_state, input);
- add_face_constraints(&cdt_state, input, output_type);
+ int actual_nf = add_face_constraints(&cdt_state, input, output_type);
+ if (actual_nf == 0 && !ELEM(output_type, CDT_FULL, CDT_INSIDE, CDT_CONSTRAINTS)) {
+ /* Can't look for faces or holes if there were no valid input faces. */
+ output_type = CDT_INSIDE;
+ }
return get_cdt_output(&cdt_state, input, output_type);
}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 27f8f1d4bc8..26a0479f445 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -382,9 +382,9 @@ static bool delete_recursive(const char *dir)
{
struct direntry *filelist, *fl;
bool err = false;
- uint nbr, i;
+ uint filelist_num, i;
- i = nbr = BLI_filelist_dir_contents(dir, &filelist);
+ i = filelist_num = BLI_filelist_dir_contents(dir, &filelist);
fl = filelist;
while (i--) {
const char *file = BLI_path_basename(fl->path);
@@ -415,7 +415,7 @@ static bool delete_recursive(const char *dir)
err = true;
}
- BLI_filelist_free(filelist, nbr);
+ BLI_filelist_free(filelist, filelist_num);
return err;
}
diff --git a/source/blender/blenlib/intern/generic_virtual_array.cc b/source/blender/blenlib/intern/generic_virtual_array.cc
index c6abf3624e1..8a6ef8e792f 100644
--- a/source/blender/blenlib/intern/generic_virtual_array.cc
+++ b/source/blender/blenlib/intern/generic_virtual_array.cc
@@ -391,10 +391,7 @@ void GVMutableArray_GSpan::save()
if (data_ != owned_data_) {
return;
}
- const int64_t element_size = type_->size();
- for (int64_t i : IndexRange(size_)) {
- varray_.set_by_copy(i, POINTER_OFFSET(owned_data_, element_size * i));
- }
+ varray_.set_all(owned_data_);
}
void GVMutableArray_GSpan::disable_not_applied_warning()
diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c
index 14baca891c0..53fbc16f3fc 100644
--- a/source/blender/blenlib/intern/math_statistics.c
+++ b/source/blender/blenlib/intern/math_statistics.c
@@ -21,7 +21,7 @@ typedef struct CovarianceData {
float *r_covmat;
float covfac;
int n;
- int nbr_cos_vn;
+ int cos_vn_num;
} CovarianceData;
static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
@@ -33,7 +33,7 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
const float *center = data->center;
float *r_covmat = data->r_covmat;
const int n = data->n;
- const int nbr_cos_vn = data->nbr_cos_vn;
+ const int cos_vn_num = data->cos_vn_num;
int k;
@@ -55,12 +55,12 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
}
if (center) {
- for (k = 0; k < nbr_cos_vn; k++) {
+ for (k = 0; k < cos_vn_num; k++) {
r_covmat[a] += (cos_vn[k * n + i] - center[i]) * (cos_vn[k * n + j] - center[j]);
}
}
else {
- for (k = 0; k < nbr_cos_vn; k++) {
+ for (k = 0; k < cos_vn_num; k++) {
r_covmat[a] += cos_vn[k * n + i] * cos_vn[k * n + j];
}
}
@@ -73,7 +73,7 @@ static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
void BLI_covariance_m_vn_ex(const int n,
const float *cos_vn,
- const int nbr_cos_vn,
+ const int cos_vn_num,
const float *center,
const bool use_sample_correction,
float *r_covmat)
@@ -81,7 +81,7 @@ void BLI_covariance_m_vn_ex(const int n,
/* Note about that division: see https://en.wikipedia.org/wiki/Bessel%27s_correction.
* In a nutshell, it must be 1 / (n - 1) for 'sample data', and 1 / n for 'population data'...
*/
- const float covfac = 1.0f / (float)(use_sample_correction ? nbr_cos_vn - 1 : nbr_cos_vn);
+ const float covfac = 1.0f / (float)(use_sample_correction ? cos_vn_num - 1 : cos_vn_num);
memset(r_covmat, 0, sizeof(*r_covmat) * (size_t)(n * n));
@@ -91,27 +91,27 @@ void BLI_covariance_m_vn_ex(const int n,
.r_covmat = r_covmat,
.covfac = covfac,
.n = n,
- .nbr_cos_vn = nbr_cos_vn,
+ .cos_vn_num = cos_vn_num,
};
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = ((nbr_cos_vn * n * n) >= 10000);
+ settings.use_threading = ((cos_vn_num * n * n) >= 10000);
BLI_task_parallel_range(0, n * n, &data, covariance_m_vn_ex_task_cb, &settings);
}
void BLI_covariance_m3_v3n(const float (*cos_v3)[3],
- const int nbr_cos_v3,
+ const int cos_v3_num,
const bool use_sample_correction,
float r_covmat[3][3],
float r_center[3])
{
float center[3];
- const float mean_fac = 1.0f / (float)nbr_cos_v3;
+ const float mean_fac = 1.0f / (float)cos_v3_num;
int i;
zero_v3(center);
- for (i = 0; i < nbr_cos_v3; i++) {
+ for (i = 0; i < cos_v3_num; i++) {
/* Applying mean_fac here rather than once at the end reduce compute errors... */
madd_v3_v3fl(center, cos_v3[i], mean_fac);
}
@@ -121,5 +121,5 @@ void BLI_covariance_m3_v3n(const float (*cos_v3)[3],
}
BLI_covariance_m_vn_ex(
- 3, (const float *)cos_v3, nbr_cos_v3, center, use_sample_correction, (float *)r_covmat);
+ 3, (const float *)cos_v3, cos_v3_num, center, use_sample_correction, (float *)r_covmat);
}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index da6a6dff16f..5dcdabaf760 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -268,12 +268,12 @@ void mid_v3_v3v3v3v3(
v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
}
-void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint nbr)
+void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const uint vec_arr_num)
{
- const float factor = 1.0f / (float)nbr;
+ const float factor = 1.0f / (float)vec_arr_num;
zero_v3(r);
- for (uint i = 0; i < nbr; i++) {
+ for (uint i = 0; i < vec_arr_num; i++) {
madd_v3_v3fl(r, vec_arr[i], factor);
}
}
@@ -904,9 +904,12 @@ void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
}
}
-void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr)
+void minmax_v3v3_v3_array(float r_min[3],
+ float r_max[3],
+ const float (*vec_arr)[3],
+ int var_arr_num)
{
- while (nbr--) {
+ while (var_arr_num--) {
minmax_v3v3_v3(r_min, r_max, *vec_arr++);
}
}
diff --git a/source/blender/blenlib/intern/timeit.cc b/source/blender/blenlib/intern/timeit.cc
index 2dcfe2e6ab1..f11f9c4ad94 100644
--- a/source/blender/blenlib/intern/timeit.cc
+++ b/source/blender/blenlib/intern/timeit.cc
@@ -2,6 +2,8 @@
#include "BLI_timeit.hh"
+#include <algorithm>
+
namespace blender::timeit {
void print_duration(Nanoseconds duration)
@@ -17,4 +19,20 @@ void print_duration(Nanoseconds duration)
}
}
+ScopedTimerAveraged::~ScopedTimerAveraged()
+{
+ const TimePoint end = Clock::now();
+ const Nanoseconds duration = end - start_;
+
+ total_count_++;
+ total_time_ += duration;
+ min_time_ = std::min(duration, min_time_);
+
+ std::cout << "Timer '" << name_ << "': (Average: ";
+ print_duration(total_time_ / total_count_);
+ std::cout << ", Min: ";
+ print_duration(min_time_);
+ std::cout << ")\n";
+}
+
} // namespace blender::timeit
diff --git a/source/blender/blenlib/tests/BLI_math_base_test.cc b/source/blender/blenlib/tests/BLI_math_base_test.cc
index 62f2b2775d0..dd35deef4a8 100644
--- a/source/blender/blenlib/tests/BLI_math_base_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_base_test.cc
@@ -151,4 +151,9 @@ TEST(math_base, Midpoint)
EXPECT_NEAR(math::midpoint(100.0f, 200.0f), 150.0f, 1e-4f);
}
+TEST(math_base, InterpolateInt)
+{
+ EXPECT_EQ(math::interpolate(100, 200, 0.4f), 140);
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_math_vector_test.cc b/source/blender/blenlib/tests/BLI_math_vector_test.cc
index 8c310645d6d..282be5f1963 100644
--- a/source/blender/blenlib/tests/BLI_math_vector_test.cc
+++ b/source/blender/blenlib/tests/BLI_math_vector_test.cc
@@ -85,4 +85,24 @@ TEST(math_vector, Clamp)
EXPECT_EQ(result_2.z, -50);
}
+TEST(math_vector, InterpolateInt)
+{
+ const int3 a(0, -100, 50);
+ const int3 b(0, 100, 100);
+ const int3 result = math::interpolate(a, b, 0.75);
+ EXPECT_EQ(result.x, 0);
+ EXPECT_EQ(result.y, 50);
+ EXPECT_EQ(result.z, 87);
+}
+
+TEST(math_vector, InterpolateFloat)
+{
+ const float3 a(40.0f, -100.0f, 50.0f);
+ const float3 b(20.0f, 100.0f, 100.0f);
+ const float3 result = math::interpolate(a, b, 0.5);
+ EXPECT_FLOAT_EQ(result.x, 30.0f);
+ EXPECT_FLOAT_EQ(result.y, 0.0f);
+ EXPECT_FLOAT_EQ(result.z, 75.0f);
+}
+
} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
index eae90f130cd..0ff488202c2 100644
--- a/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_ghash_performance_test.cc
@@ -177,17 +177,17 @@ TEST(ghash, TextMurmur2a)
/* Int: uniform 100M first integers. */
-static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr)
+static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
{
printf("\n========== STARTING %s ==========\n", id);
{
- unsigned int i = nbr;
+ unsigned int i = count;
TIMEIT_START(int_insert);
#ifdef GHASH_RESERVE
- BLI_ghash_reserve(ghash, nbr);
+ BLI_ghash_reserve(ghash, count);
#endif
while (i--) {
@@ -200,7 +200,7 @@ static void int_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr
PRINTF_GHASH_STATS(ghash);
{
- unsigned int i = nbr;
+ unsigned int i = count;
TIMEIT_START(int_lookup);
@@ -266,17 +266,17 @@ TEST(ghash, IntMurmur2a100000000)
/* Int: random 50M integers. */
-static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr)
+static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
{
printf("\n========== STARTING %s ==========\n", id);
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)nbr, __func__);
+ unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
unsigned int *dt;
unsigned int i;
{
RNG *rng = BLI_rng_new(1);
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
*dt = BLI_rng_get_uint(rng);
}
BLI_rng_free(rng);
@@ -286,10 +286,10 @@ static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int
TIMEIT_START(int_insert);
#ifdef GHASH_RESERVE
- BLI_ghash_reserve(ghash, nbr);
+ BLI_ghash_reserve(ghash, count);
#endif
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
BLI_ghash_insert(ghash, POINTER_FROM_UINT(*dt), POINTER_FROM_UINT(*dt));
}
@@ -301,7 +301,7 @@ static void randint_ghash_tests(GHash *ghash, const char *id, const unsigned int
{
TIMEIT_START(int_lookup);
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
void *v = BLI_ghash_lookup(ghash, POINTER_FROM_UINT(*dt));
EXPECT_EQ(POINTER_AS_UINT(v), *dt);
}
@@ -375,18 +375,18 @@ TEST(ghash, Int4NoHash50000000)
/* Int_v4: 20M of randomly-generated integer vectors. */
-static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr)
+static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
{
printf("\n========== STARTING %s ==========\n", id);
- void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)nbr, __func__);
+ void *data_v = MEM_mallocN(sizeof(unsigned int[4]) * (size_t)count, __func__);
unsigned int(*data)[4] = (unsigned int(*)[4])data_v;
unsigned int(*dt)[4];
unsigned int i, j;
{
RNG *rng = BLI_rng_new(1);
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
for (j = 4; j--;) {
(*dt)[j] = BLI_rng_get_uint(rng);
}
@@ -398,10 +398,10 @@ static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nb
TIMEIT_START(int_v4_insert);
#ifdef GHASH_RESERVE
- BLI_ghash_reserve(ghash, nbr);
+ BLI_ghash_reserve(ghash, count);
#endif
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
BLI_ghash_insert(ghash, *dt, POINTER_FROM_UINT(i));
}
@@ -413,7 +413,7 @@ static void int4_ghash_tests(GHash *ghash, const char *id, const unsigned int nb
{
TIMEIT_START(int_v4_lookup);
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
void *v = BLI_ghash_lookup(ghash, (void *)(*dt));
EXPECT_EQ(POINTER_AS_UINT(v), i);
}
@@ -483,25 +483,25 @@ TEST(ghash, Int2NoHash50000000)
/* MultiSmall: create and manipulate a lot of very small ghash's
* (90% < 10 items, 9% < 100 items, 1% < 1000 items). */
-static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int nbr)
+static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned int count)
{
- unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)nbr, __func__);
+ unsigned int *data = (unsigned int *)MEM_mallocN(sizeof(*data) * (size_t)count, __func__);
unsigned int *dt;
unsigned int i;
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
*dt = BLI_rng_get_uint(rng);
}
#ifdef GHASH_RESERVE
- BLI_ghash_reserve(ghash, nbr);
+ BLI_ghash_reserve(ghash, count);
#endif
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
BLI_ghash_insert(ghash, POINTER_FROM_UINT(*dt), POINTER_FROM_UINT(*dt));
}
- for (i = nbr, dt = data; i--; dt++) {
+ for (i = count, dt = data; i--; dt++) {
void *v = BLI_ghash_lookup(ghash, POINTER_FROM_UINT(*dt));
EXPECT_EQ(POINTER_AS_UINT(v), *dt);
}
@@ -510,7 +510,7 @@ static void multi_small_ghash_tests_one(GHash *ghash, RNG *rng, const unsigned i
MEM_freeN(data);
}
-static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int nbr)
+static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned int count)
{
printf("\n========== STARTING %s ==========\n", id);
@@ -518,22 +518,22 @@ static void multi_small_ghash_tests(GHash *ghash, const char *id, const unsigned
TIMEIT_START(multi_small_ghash);
- unsigned int i = nbr;
+ unsigned int i = count;
while (i--) {
- const int nbr = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) *
- (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
- multi_small_ghash_tests_one(ghash, rng, nbr);
+ const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) *
+ (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
+ multi_small_ghash_tests_one(ghash, rng, count);
}
TIMEIT_END(multi_small_ghash);
TIMEIT_START(multi_small2_ghash);
- unsigned int i = nbr;
+ unsigned int i = count;
while (i--) {
- const int nbr = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 *
- (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
- multi_small_ghash_tests_one(ghash, rng, nbr);
+ const int count = 1 + (BLI_rng_get_int(rng) % TESTCASE_SIZE_SMALL) / 2 *
+ (!(i % 100) ? 100 : (!(i % 10) ? 10 : 1));
+ multi_small_ghash_tests_one(ghash, rng, count);
}
TIMEIT_END(multi_small2_ghash);
diff --git a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
index 33a196569e9..98fafe55d69 100644
--- a/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
+++ b/source/blender/blenlib/tests/performance/BLI_task_performance_test.cc
@@ -135,17 +135,17 @@ static void task_listbase_test_do(ListBase *list,
NUM_RUN_AVERAGED);
}
-static void task_listbase_test(const char *id, const int nbr, const bool use_threads)
+static void task_listbase_test(const char *id, const int count, const bool use_threads)
{
printf("\n========== STARTING %s ==========\n", id);
ListBase list = {nullptr, nullptr};
- LinkData *items_buffer = (LinkData *)MEM_calloc_arrayN(nbr, sizeof(*items_buffer), __func__);
+ LinkData *items_buffer = (LinkData *)MEM_calloc_arrayN(count, sizeof(*items_buffer), __func__);
BLI_threadapi_init();
int num_items = 0;
- for (int i = 0; i < nbr; i++) {
+ for (int i = 0; i < count; i++) {
BLI_addtail(&list, &items_buffer[i]);
num_items++;
}
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index d71bfd27a7f..2f6bec4061a 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -1571,10 +1571,10 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_SurfaceDeform) {
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- if (smd->num_bind_verts && smd->verts) {
- smd->num_mesh_verts = smd->num_bind_verts;
+ if (smd->bind_verts_num && smd->verts) {
+ smd->mesh_verts_num = smd->bind_verts_num;
- for (unsigned int i = 0; i < smd->num_bind_verts; i++) {
+ for (unsigned int i = 0; i < smd->bind_verts_num; i++) {
smd->verts[i].vertex_idx = i;
}
}
@@ -2417,6 +2417,24 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* Change grease pencil smooth iterations to match old results with new algorithm. */
+ LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
+ LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
+ if (md->type == eGpencilModifierType_Smooth) {
+ SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
+ if (gpmd->step == 1 && gpmd->factor <= 0.5f) {
+ gpmd->factor *= 2.0f;
+ }
+ else {
+ gpmd->step = 1 + (int)(gpmd->factor * max_ff(0.0f,
+ min_ff(5.1f * sqrtf(gpmd->step) - 3.0f,
+ gpmd->step + 2.0f)));
+ gpmd->factor = 1.0f;
+ }
+ }
+ }
+ }
}
/* rebuild active/render color attribute references*/
@@ -2496,5 +2514,16 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
scene->toolsettings->curves_sculpt->curve_length = 0.3f;
}
}
+
+ for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
+ LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
+ LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
+ if (sl->spacetype == SPACE_OUTLINER) {
+ SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
+ space_outliner->filter &= ~SO_FILTER_CLEARED_1;
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 5b026c1cca0..16297149cc3 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -2064,8 +2064,8 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
}
for (part = bmain->particles.first; part; part = part->id.next) {
- if (part->ren_child_nbr == 0) {
- part->ren_child_nbr = part->child_nbr;
+ if (part->child_render_percent == 0) {
+ part->child_render_percent = part->child_percent;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
index 118e7751cbc..40f1d7c496d 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc
@@ -1096,7 +1096,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
vertMap = bm_to_mesh_vertex_map(bm, ototvert);
}
- for (i = j = 0; i < hmd->totindex; i++) {
+ for (i = j = 0; i < hmd->indexar_num; i++) {
if (hmd->indexar[i] < ototvert) {
eve = vertMap[hmd->indexar[i]];
@@ -1109,7 +1109,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh
}
}
- hmd->totindex = j;
+ hmd->indexar_num = j;
}
}
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.c b/source/blender/bmesh/intern/bmesh_mesh_normals.c
index d61b2c5bb43..cd89a550279 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_normals.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_normals.c
@@ -580,7 +580,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm,
/* We validate clnors data on the fly - cheapest way to do! */
int clnors_avg[2] = {0, 0};
const short(*clnor_ref)[2] = NULL;
- int clnors_nbr = 0;
+ int clnors_count = 0;
bool clnors_invalid = false;
const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
@@ -649,7 +649,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm,
const short(*clnor)[2] = clnors_data ? &clnors_data[lfan_pivot_index] :
(const void *)BM_ELEM_CD_GET_VOID_P(
lfan_pivot, cd_loop_clnors_offset);
- if (clnors_nbr) {
+ if (clnors_count) {
clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
}
else {
@@ -657,7 +657,7 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm,
}
clnors_avg[0] += (*clnor)[0];
clnors_avg[1] += (*clnor)[1];
- clnors_nbr++;
+ clnors_count++;
/* We store here a pointer to all custom lnors processed. */
BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
}
@@ -706,8 +706,8 @@ static int bm_mesh_loops_calc_normals_for_loop(BMesh *bm,
if (clnors_invalid) {
short *clnor;
- clnors_avg[0] /= clnors_nbr;
- clnors_avg[1] /= clnors_nbr;
+ clnors_avg[0] /= clnors_count;
+ clnors_avg[1] /= clnors_count;
/* Fix/update all clnors of this fan with computed average value. */
/* Prints continuously when merge custom normals, so commenting. */
@@ -1517,7 +1517,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm,
BLI_BITMAP_ENABLE(done_loops, i);
}
else {
- int nbr_nors = 0;
+ int avg_nor_count = 0;
float avg_nor[3];
short clnor_data_tmp[2], *clnor_data;
@@ -1530,7 +1530,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm,
short *clnor = r_clnors_data ? &r_clnors_data[lidx] :
BM_ELEM_CD_GET_VOID_P(ml, cd_loop_clnors_offset);
- nbr_nors++;
+ avg_nor_count++;
add_v3_v3(avg_nor, nor);
BLI_SMALLSTACK_PUSH(clnors_data, clnor);
@@ -1538,7 +1538,7 @@ static void bm_mesh_loops_assign_normal_data(BMesh *bm,
BLI_BITMAP_ENABLE(done_loops, lidx);
}
- mul_v3_fl(avg_nor, 1.0f / (float)nbr_nors);
+ mul_v3_fl(avg_nor, 1.0f / (float)avg_nor_count);
BKE_lnor_space_custom_normal_to_data(
lnors_spacearr->lspacearr[i], avg_nor, clnor_data_tmp);
diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc
index 0d9d3b111b0..66dbabe71b5 100644
--- a/source/blender/compositor/intern/COM_Debug.cc
+++ b/source/blender/compositor/intern/COM_Debug.cc
@@ -468,8 +468,8 @@ void DebugInfo::delete_operation_exports()
const std::string dir = get_operations_export_dir();
if (BLI_exists(dir.c_str())) {
struct direntry *file_list;
- int num_files = BLI_filelist_dir_contents(dir.c_str(), &file_list);
- for (int i = 0; i < num_files; i++) {
+ int file_list_num = BLI_filelist_dir_contents(dir.c_str(), &file_list);
+ for (int i = 0; i < file_list_num; i++) {
direntry *file = &file_list[i];
const eFileAttributes file_attrs = BLI_file_attributes(file->path);
if (file_attrs & FILE_ATTR_ANY_LINK) {
@@ -480,7 +480,7 @@ void DebugInfo::delete_operation_exports()
BLI_delete(file->path, false, false);
}
}
- BLI_filelist_free(file_list, num_files);
+ BLI_filelist_free(file_list, file_list_num);
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 5788e8efa07..bcde1839a0f 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -54,7 +54,7 @@ void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
{
#ifdef INVALIDATE_WORK_DATA
BLI_assert(data != nullptr);
- memset(&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
+ memset((void *)&data->temp_dupli_object, 0xff, sizeof(data->temp_dupli_object));
#else
(void)data;
#endif
@@ -167,7 +167,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
/* Temporary object to evaluate. */
Object *dupli_parent = data->dupli_parent;
Object *temp_dupli_object = &data->temp_dupli_object;
- *temp_dupli_object = *dob->ob;
+ *temp_dupli_object = blender::dna::shallow_copy(*dob->ob);
temp_dupli_object->base_flag = dupli_parent->base_flag | BASE_FROM_DUPLI;
temp_dupli_object->base_local_view_bits = dupli_parent->base_local_view_bits;
temp_dupli_object->runtime.local_collections_bits =
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 5dd26d19e02..2a2335aa44c 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -25,10 +25,10 @@ set(INC
../windowmanager
../../../intern/atomic
+ ../../../intern/clog
../../../intern/glew-mx
../../../intern/guardedalloc
../../../intern/opensubdiv
- ../../../intern/clog
# dna_type_offsets.h
${CMAKE_CURRENT_BINARY_DIR}/../makesdna/intern
@@ -190,6 +190,7 @@ set(SRC
intern/draw_cache_inline.h
intern/draw_color_management.h
intern/draw_common.h
+ intern/draw_common_shader_shared.h
intern/draw_debug.h
intern/draw_hair_private.h
intern/draw_instance_data.h
@@ -221,9 +222,9 @@ set(SRC
engines/image/image_partial_updater.hh
engines/image/image_private.hh
engines/image/image_shader_params.hh
+ engines/image/image_space.hh
engines/image/image_space_image.hh
engines/image/image_space_node.hh
- engines/image/image_space.hh
engines/image/image_texture_info.hh
engines/image/image_usage.hh
engines/image/image_wrappers.hh
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
index 96b0df5b7db..25939926cfa 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
@@ -116,7 +116,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
EEVEE_ShadowCascade *csm_data = linfo->shadow_cascade_data + (int)shdw_data->type_data_id;
EEVEE_ShadowCascadeRender *csm_render = linfo->shadow_cascade_render +
(int)shdw_data->type_data_id;
- int cascade_nbr = csm_render->cascade_count;
+ int cascade_count = csm_render->cascade_count;
float cascade_fade = csm_render->cascade_fade;
float cascade_max_dist = csm_render->cascade_max_dist;
float cascade_exponent = csm_render->cascade_exponent;
@@ -223,19 +223,19 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
float p[4] = {1.0f, 1.0f, csm_end, 1.0f};
/* TODO: we don't need full m4 multiply here */
mul_m4_v4(vp_projmat, p);
- splits_end_ndc[cascade_nbr - 1] = p[2];
+ splits_end_ndc[cascade_count - 1] = p[2];
if (is_persp) {
- splits_end_ndc[cascade_nbr - 1] /= p[3];
+ splits_end_ndc[cascade_count - 1] /= p[3];
}
}
csm_data->split_start[0] = csm_start;
- csm_data->split_end[cascade_nbr - 1] = csm_end;
+ csm_data->split_end[cascade_count - 1] = csm_end;
- for (int c = 1; c < cascade_nbr; c++) {
+ for (int c = 1; c < cascade_count; c++) {
/* View Space */
- float linear_split = interpf(csm_end, csm_start, c / (float)cascade_nbr);
- float exp_split = csm_start * powf(csm_end / csm_start, c / (float)cascade_nbr);
+ float linear_split = interpf(csm_end, csm_start, c / (float)cascade_count);
+ float exp_split = csm_start * powf(csm_end / csm_start, c / (float)cascade_count);
if (is_persp) {
csm_data->split_start[c] = interpf(exp_split, linear_split, cascade_exponent);
@@ -276,13 +276,13 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
}
/* Set last cascade split fade distance into the first split_start. */
- float prev_split = (cascade_nbr > 1) ? csm_data->split_end[cascade_nbr - 2] :
- csm_data->split_start[0];
+ float prev_split = (cascade_count > 1) ? csm_data->split_end[cascade_count - 2] :
+ csm_data->split_start[0];
csm_data->split_start[0] = interpf(
- prev_split, csm_data->split_end[cascade_nbr - 1], cascade_fade);
+ prev_split, csm_data->split_end[cascade_count - 1], cascade_fade);
/* For each cascade */
- for (int c = 0; c < cascade_nbr; c++) {
+ for (int c = 0; c < cascade_count; c++) {
float(*projmat)[4] = csm_render->projmat[c];
/* Given 8 frustum corners */
float corners[8][3] = {
diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh
index 46482ab6668..f43bbadfa91 100644
--- a/source/blender/draw/engines/image/image_drawing_mode.hh
+++ b/source/blender/draw/engines/image/image_drawing_mode.hh
@@ -154,16 +154,15 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
* bug or a feature. For now we just acquire to determine if there is a texture. */
void *lock;
ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock);
- if (tile_buffer == nullptr) {
- continue;
+ if (tile_buffer != nullptr) {
+ instance_data.float_buffers.mark_used(tile_buffer);
+
+ DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp);
+ float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1);
+ DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv);
+ DRW_shgroup_call_obmat(shsub, info.batch, image_mat);
}
- instance_data.float_buffers.mark_used(tile_buffer);
BKE_image_release_ibuf(image, tile_buffer, lock);
-
- DRWShadingGroup *shsub = DRW_shgroup_create_sub(shgrp);
- float4 min_max_uv(tile_x, tile_y, tile_x + 1, tile_y + 1);
- DRW_shgroup_uniform_vec4_copy(shsub, "min_max_uv", min_max_uv);
- DRW_shgroup_call_obmat(shsub, info.batch, image_mat);
}
}
}
@@ -387,11 +386,9 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD
tile_user.tile = image_tile.get_tile_number();
ImBuf *tile_buffer = BKE_image_acquire_ibuf(image, &tile_user, &lock);
- if (tile_buffer == nullptr) {
- /* Couldn't load the image buffer of the tile. */
- continue;
+ if (tile_buffer != nullptr) {
+ do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile);
}
- do_full_update_texture_slot(instance_data, info, texture_buffer, *tile_buffer, image_tile);
BKE_image_release_ibuf(image, tile_buffer, lock);
}
GPU_texture_update(info.texture, GPU_DATA_FLOAT, texture_buffer.rect_float);
diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc
index f772f132b13..a21a6409ca5 100644
--- a/source/blender/draw/intern/draw_cache_impl_curves.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curves.cc
@@ -138,7 +138,7 @@ static void curves_batch_cache_fill_segments_proc_pos(Curves *curves,
Span<float3> positions = geometry.positions();
for (const int i : IndexRange(curve_size)) {
- const IndexRange curve_range = geometry.range_for_curve(i);
+ const IndexRange curve_range = geometry.points_for_curve(i);
Span<float3> curve_positions = positions.slice(curve_range);
float total_len = 0.0f;
@@ -218,8 +218,8 @@ static void curves_batch_cache_fill_strands_data(Curves *curves,
const blender::bke::CurvesGeometry &geometry = blender::bke::CurvesGeometry::wrap(
curves->geometry);
- for (const int i : IndexRange(geometry.curves_size())) {
- const IndexRange curve_range = geometry.range_for_curve(i);
+ for (const int i : IndexRange(geometry.curves_num())) {
+ const IndexRange curve_range = geometry.points_for_curve(i);
*(uint *)GPU_vertbuf_raw_step(data_step) = curve_range.start();
*(ushort *)GPU_vertbuf_raw_step(seg_step) = curve_range.size() - 1;
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index c7edf003346..462ae6f7cf1 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -184,9 +184,10 @@ void DRW_globals_update(void)
gb->pixelFac = *DRW_viewport_pixelsize_get();
- copy_v2_v2(gb->sizeViewport, DRW_viewport_size_get());
- copy_v2_v2(gb->sizeViewportInv, gb->sizeViewport);
- invert_v2(gb->sizeViewportInv);
+ /* Deprecated, use drw_view.viewport_size instead */
+ copy_v2_v2(&gb->sizeViewport[0], DRW_viewport_size_get());
+ copy_v2_v2(&gb->sizeViewport[2], &gb->sizeViewport[0]);
+ invert_v2(&gb->sizeViewport[2]);
/* Color management. */
{
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index 53946c0cec5..e2dc91f64be 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -7,6 +7,8 @@
#pragma once
+#include "draw_common_shader_shared.h"
+
struct DRWShadingGroup;
struct FluidModifierData;
struct GPUMaterial;
@@ -16,126 +18,6 @@ struct ParticleSystem;
struct RegionView3D;
struct ViewLayer;
-#define UBO_FIRST_COLOR colorWire
-#define UBO_LAST_COLOR colorUVShadow
-
-/* Used as ubo but colors can be directly referenced as well */
-/* Keep in sync with: common_globals_lib.glsl (globalsBlock) */
-/* NOTE: Also keep all color as vec4 and between #UBO_FIRST_COLOR and #UBO_LAST_COLOR. */
-typedef struct GlobalsUboStorage {
- /* UBOs data needs to be 16 byte aligned (size of vec4) */
- float colorWire[4];
- float colorWireEdit[4];
- float colorActive[4];
- float colorSelect[4];
- float colorLibrarySelect[4];
- float colorLibrary[4];
- float colorTransform[4];
- float colorLight[4];
- float colorSpeaker[4];
- float colorCamera[4];
- float colorCameraPath[4];
- float colorEmpty[4];
- float colorVertex[4];
- float colorVertexSelect[4];
- float colorVertexUnreferenced[4];
- float colorVertexMissingData[4];
- float colorEditMeshActive[4];
- float colorEdgeSelect[4];
- float colorEdgeSeam[4];
- float colorEdgeSharp[4];
- float colorEdgeCrease[4];
- float colorEdgeBWeight[4];
- float colorEdgeFaceSelect[4];
- float colorEdgeFreestyle[4];
- float colorFace[4];
- float colorFaceSelect[4];
- float colorFaceFreestyle[4];
- float colorGpencilVertex[4];
- float colorGpencilVertexSelect[4];
- float colorNormal[4];
- float colorVNormal[4];
- float colorLNormal[4];
- float colorFaceDot[4];
- float colorSkinRoot[4];
-
- float colorDeselect[4];
- float colorOutline[4];
- float colorLightNoAlpha[4];
-
- float colorBackground[4];
- float colorBackgroundGradient[4];
- float colorCheckerPrimary[4];
- float colorCheckerSecondary[4];
- float colorClippingBorder[4];
- float colorEditMeshMiddle[4];
-
- float colorHandleFree[4];
- float colorHandleAuto[4];
- float colorHandleVect[4];
- float colorHandleAlign[4];
- float colorHandleAutoclamp[4];
- float colorHandleSelFree[4];
- float colorHandleSelAuto[4];
- float colorHandleSelVect[4];
- float colorHandleSelAlign[4];
- float colorHandleSelAutoclamp[4];
- float colorNurbUline[4];
- float colorNurbVline[4];
- float colorNurbSelUline[4];
- float colorNurbSelVline[4];
- float colorActiveSpline[4];
-
- float colorBonePose[4];
- float colorBonePoseActive[4];
- float colorBonePoseActiveUnsel[4];
- float colorBonePoseConstraint[4];
- float colorBonePoseIK[4];
- float colorBonePoseSplineIK[4];
- float colorBonePoseTarget[4];
- float colorBoneSolid[4];
- float colorBoneLocked[4];
- float colorBoneActive[4];
- float colorBoneActiveUnsel[4];
- float colorBoneSelect[4];
- float colorBoneIKLine[4];
- float colorBoneIKLineNoTarget[4];
- float colorBoneIKLineSpline[4];
-
- float colorText[4];
- float colorTextHi[4];
-
- float colorBundleSolid[4];
-
- float colorMballRadius[4];
- float colorMballRadiusSelect[4];
- float colorMballStiffness[4];
- float colorMballStiffnessSelect[4];
-
- float colorCurrentFrame[4];
-
- float colorGrid[4];
- float colorGridEmphasis[4];
- float colorGridAxisX[4];
- float colorGridAxisY[4];
- float colorGridAxisZ[4];
-
- float colorFaceBack[4];
- float colorFaceFront[4];
-
- float colorUVShadow[4];
-
- /* NOTE: Put all color before #UBO_LAST_COLOR. */
- float screenVecs[2][4]; /* Padded as vec4. */
- float sizeViewport[2], sizeViewportInv[2]; /* Packed as vec4 in GLSL. */
-
- /* Pack individual float at the end of the buffer to avoid alignment errors */
- float sizePixel, pixelFac;
- float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow;
- float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot;
- float sizeChecker;
- float sizeVertexGpencil;
-} GlobalsUboStorage;
/* Keep in sync with globalsBlock in shaders */
BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)
diff --git a/source/blender/draw/intern/draw_common_shader_shared.h b/source/blender/draw/intern/draw_common_shader_shared.h
new file mode 100644
index 00000000000..c83af2eef84
--- /dev/null
+++ b/source/blender/draw/intern/draw_common_shader_shared.h
@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. */
+
+/** \file
+ * \ingroup draw
+ */
+
+#ifndef GPU_SHADER
+# include "GPU_shader_shared_utils.h"
+
+typedef struct GlobalsUboStorage GlobalsUboStorage;
+#endif
+
+/* Future Plan: These globals were once shared between multiple overlay engines. But now that they
+ * have been merged into one engine, there is no reasons to keep these globals out of the overlay
+ * engine. */
+
+#define UBO_FIRST_COLOR colorWire
+#define UBO_LAST_COLOR colorUVShadow
+
+/* Used as ubo but colors can be directly referenced as well */
+/* NOTE: Also keep all color as vec4 and between #UBO_FIRST_COLOR and #UBO_LAST_COLOR. */
+struct GlobalsUboStorage {
+ /* UBOs data needs to be 16 byte aligned (size of vec4) */
+ float4 colorWire;
+ float4 colorWireEdit;
+ float4 colorActive;
+ float4 colorSelect;
+ float4 colorLibrarySelect;
+ float4 colorLibrary;
+ float4 colorTransform;
+ float4 colorLight;
+ float4 colorSpeaker;
+ float4 colorCamera;
+ float4 colorCameraPath;
+ float4 colorEmpty;
+ float4 colorVertex;
+ float4 colorVertexSelect;
+ float4 colorVertexUnreferenced;
+ float4 colorVertexMissingData;
+ float4 colorEditMeshActive;
+ float4 colorEdgeSelect;
+ float4 colorEdgeSeam;
+ float4 colorEdgeSharp;
+ float4 colorEdgeCrease;
+ float4 colorEdgeBWeight;
+ float4 colorEdgeFaceSelect;
+ float4 colorEdgeFreestyle;
+ float4 colorFace;
+ float4 colorFaceSelect;
+ float4 colorFaceFreestyle;
+ float4 colorGpencilVertex;
+ float4 colorGpencilVertexSelect;
+ float4 colorNormal;
+ float4 colorVNormal;
+ float4 colorLNormal;
+ float4 colorFaceDot;
+ float4 colorSkinRoot;
+
+ float4 colorDeselect;
+ float4 colorOutline;
+ float4 colorLightNoAlpha;
+
+ float4 colorBackground;
+ float4 colorBackgroundGradient;
+ float4 colorCheckerPrimary;
+ float4 colorCheckerSecondary;
+ float4 colorClippingBorder;
+ float4 colorEditMeshMiddle;
+
+ float4 colorHandleFree;
+ float4 colorHandleAuto;
+ float4 colorHandleVect;
+ float4 colorHandleAlign;
+ float4 colorHandleAutoclamp;
+ float4 colorHandleSelFree;
+ float4 colorHandleSelAuto;
+ float4 colorHandleSelVect;
+ float4 colorHandleSelAlign;
+ float4 colorHandleSelAutoclamp;
+ float4 colorNurbUline;
+ float4 colorNurbVline;
+ float4 colorNurbSelUline;
+ float4 colorNurbSelVline;
+ float4 colorActiveSpline;
+
+ float4 colorBonePose;
+ float4 colorBonePoseActive;
+ float4 colorBonePoseActiveUnsel;
+ float4 colorBonePoseConstraint;
+ float4 colorBonePoseIK;
+ float4 colorBonePoseSplineIK;
+ float4 colorBonePoseTarget;
+ float4 colorBoneSolid;
+ float4 colorBoneLocked;
+ float4 colorBoneActive;
+ float4 colorBoneActiveUnsel;
+ float4 colorBoneSelect;
+ float4 colorBoneIKLine;
+ float4 colorBoneIKLineNoTarget;
+ float4 colorBoneIKLineSpline;
+
+ float4 colorText;
+ float4 colorTextHi;
+
+ float4 colorBundleSolid;
+
+ float4 colorMballRadius;
+ float4 colorMballRadiusSelect;
+ float4 colorMballStiffness;
+ float4 colorMballStiffnessSelect;
+
+ float4 colorCurrentFrame;
+
+ float4 colorGrid;
+ float4 colorGridEmphasis;
+ float4 colorGridAxisX;
+ float4 colorGridAxisY;
+ float4 colorGridAxisZ;
+
+ float4 colorFaceBack;
+ float4 colorFaceFront;
+
+ float4 colorUVShadow;
+
+ /* NOTE: Put all color before #UBO_LAST_COLOR. */
+ float4 screenVecs[2]; /* Padded as vec4. */
+ float4 sizeViewport; /* Packed as vec4. */
+
+ /* Pack individual float at the end of the buffer to avoid alignment errors */
+ float sizePixel, pixelFac;
+ float sizeObjectCenter, sizeLightCenter, sizeLightCircle, sizeLightCircleShadow;
+ float sizeVertex, sizeEdge, sizeEdgeFix, sizeFaceDot;
+ float sizeChecker;
+ float sizeVertexGpencil;
+};
+BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)
+
+#ifdef GPU_SHADER
+/* Keep compatibility_with old global scope syntax. */
+/* TODO(@fclem) Mass rename and remove the camel case. */
+# define colorWire drw_globals.colorWire
+# define colorWireEdit drw_globals.colorWireEdit
+# define colorActive drw_globals.colorActive
+# define colorSelect drw_globals.colorSelect
+# define colorLibrarySelect drw_globals.colorLibrarySelect
+# define colorLibrary drw_globals.colorLibrary
+# define colorTransform drw_globals.colorTransform
+# define colorLight drw_globals.colorLight
+# define colorSpeaker drw_globals.colorSpeaker
+# define colorCamera drw_globals.colorCamera
+# define colorCameraPath drw_globals.colorCameraPath
+# define colorEmpty drw_globals.colorEmpty
+# define colorVertex drw_globals.colorVertex
+# define colorVertexSelect drw_globals.colorVertexSelect
+# define colorVertexUnreferenced drw_globals.colorVertexUnreferenced
+# define colorVertexMissingData drw_globals.colorVertexMissingData
+# define colorEditMeshActive drw_globals.colorEditMeshActive
+# define colorEdgeSelect drw_globals.colorEdgeSelect
+# define colorEdgeSeam drw_globals.colorEdgeSeam
+# define colorEdgeSharp drw_globals.colorEdgeSharp
+# define colorEdgeCrease drw_globals.colorEdgeCrease
+# define colorEdgeBWeight drw_globals.colorEdgeBWeight
+# define colorEdgeFaceSelect drw_globals.colorEdgeFaceSelect
+# define colorEdgeFreestyle drw_globals.colorEdgeFreestyle
+# define colorFace drw_globals.colorFace
+# define colorFaceSelect drw_globals.colorFaceSelect
+# define colorFaceFreestyle drw_globals.colorFaceFreestyle
+# define colorGpencilVertex drw_globals.colorGpencilVertex
+# define colorGpencilVertexSelect drw_globals.colorGpencilVertexSelect
+# define colorNormal drw_globals.colorNormal
+# define colorVNormal drw_globals.colorVNormal
+# define colorLNormal drw_globals.colorLNormal
+# define colorFaceDot drw_globals.colorFaceDot
+# define colorSkinRoot drw_globals.colorSkinRoot
+# define colorDeselect drw_globals.colorDeselect
+# define colorOutline drw_globals.colorOutline
+# define colorLightNoAlpha drw_globals.colorLightNoAlpha
+# define colorBackground drw_globals.colorBackground
+# define colorBackgroundGradient drw_globals.colorBackgroundGradient
+# define colorCheckerPrimary drw_globals.colorCheckerPrimary
+# define colorCheckerSecondary drw_globals.colorCheckerSecondary
+# define colorClippingBorder drw_globals.colorClippingBorder
+# define colorEditMeshMiddle drw_globals.colorEditMeshMiddle
+# define colorHandleFree drw_globals.colorHandleFree
+# define colorHandleAuto drw_globals.colorHandleAuto
+# define colorHandleVect drw_globals.colorHandleVect
+# define colorHandleAlign drw_globals.colorHandleAlign
+# define colorHandleAutoclamp drw_globals.colorHandleAutoclamp
+# define colorHandleSelFree drw_globals.colorHandleSelFree
+# define colorHandleSelAuto drw_globals.colorHandleSelAuto
+# define colorHandleSelVect drw_globals.colorHandleSelVect
+# define colorHandleSelAlign drw_globals.colorHandleSelAlign
+# define colorHandleSelAutoclamp drw_globals.colorHandleSelAutoclamp
+# define colorNurbUline drw_globals.colorNurbUline
+# define colorNurbVline drw_globals.colorNurbVline
+# define colorNurbSelUline drw_globals.colorNurbSelUline
+# define colorNurbSelVline drw_globals.colorNurbSelVline
+# define colorActiveSpline drw_globals.colorActiveSpline
+# define colorBonePose drw_globals.colorBonePose
+# define colorBonePoseActive drw_globals.colorBonePoseActive
+# define colorBonePoseActiveUnsel drw_globals.colorBonePoseActiveUnsel
+# define colorBonePoseConstraint drw_globals.colorBonePoseConstraint
+# define colorBonePoseIK drw_globals.colorBonePoseIK
+# define colorBonePoseSplineIK drw_globals.colorBonePoseSplineIK
+# define colorBonePoseTarget drw_globals.colorBonePoseTarget
+# define colorBoneSolid drw_globals.colorBoneSolid
+# define colorBoneLocked drw_globals.colorBoneLocked
+# define colorBoneActive drw_globals.colorBoneActive
+# define colorBoneActiveUnsel drw_globals.colorBoneActiveUnsel
+# define colorBoneSelect drw_globals.colorBoneSelect
+# define colorBoneIKLine drw_globals.colorBoneIKLine
+# define colorBoneIKLineNoTarget drw_globals.colorBoneIKLineNoTarget
+# define colorBoneIKLineSpline drw_globals.colorBoneIKLineSpline
+# define colorText drw_globals.colorText
+# define colorTextHi drw_globals.colorTextHi
+# define colorBundleSolid drw_globals.colorBundleSolid
+# define colorMballRadius drw_globals.colorMballRadius
+# define colorMballRadiusSelect drw_globals.colorMballRadiusSelect
+# define colorMballStiffness drw_globals.colorMballStiffness
+# define colorMballStiffnessSelect drw_globals.colorMballStiffnessSelect
+# define colorCurrentFrame drw_globals.colorCurrentFrame
+# define colorGrid drw_globals.colorGrid
+# define colorGridEmphasis drw_globals.colorGridEmphasis
+# define colorGridAxisX drw_globals.colorGridAxisX
+# define colorGridAxisY drw_globals.colorGridAxisY
+# define colorGridAxisZ drw_globals.colorGridAxisZ
+# define colorFaceBack drw_globals.colorFaceBack
+# define colorFaceFront drw_globals.colorFaceFront
+# define colorUVShadow drw_globals.colorUVShadow
+# define screenVecs drw_globals.screenVecs
+# define sizeViewport drw_globals.sizeViewport
+# define sizePixel drw_globals.sizePixel
+# define pixelFac drw_globals.pixelFac
+# define sizeObjectCenter drw_globals.sizeObjectCenter
+# define sizeLightCenter drw_globals.sizeLightCenter
+# define sizeLightCircle drw_globals.sizeLightCircle
+# define sizeLightCircleShadow drw_globals.sizeLightCircleShadow
+# define sizeVertex drw_globals.sizeVertex
+# define sizeEdge drw_globals.sizeEdge
+# define sizeEdgeFix drw_globals.sizeEdgeFix
+# define sizeFaceDot drw_globals.sizeFaceDot
+# define sizeChecker drw_globals.sizeChecker
+# define sizeVertexGpencil drw_globals.sizeVertexGpencil
+#endif
diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h
index 7c71ae9e21f..5fc76bc25e6 100644
--- a/source/blender/draw/intern/draw_shader_shared.h
+++ b/source/blender/draw/intern/draw_shader_shared.h
@@ -30,7 +30,7 @@ struct ViewInfos {
float2 viewport_size_inverse;
/** Frustum culling data. */
- /** NOTE: vec3 arrays are paded to vec4. */
+ /** NOTE: vec3 arrays are padded to vec4. */
float4 frustum_corners[8];
float4 frustum_planes[6];
};
diff --git a/source/blender/draw/intern/draw_view_data.cc b/source/blender/draw/intern/draw_view_data.cc
index 682728eb22b..0e55d28f6df 100644
--- a/source/blender/draw/intern/draw_view_data.cc
+++ b/source/blender/draw/intern/draw_view_data.cc
@@ -37,7 +37,10 @@ struct DRWViewData {
DRWViewData *DRW_view_data_create(ListBase *engine_types)
{
+ const int engine_types_len = BLI_listbase_count(engine_types);
+
DRWViewData *view_data = new DRWViewData();
+ view_data->engines.reserve(engine_types_len);
LISTBASE_FOREACH (DRWRegisteredDrawEngine *, type, engine_types) {
ViewportEngineData engine = {};
engine.engine_type = type;
diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh
index a699b9013ef..ba43938cbc0 100644
--- a/source/blender/draw/intern/shaders/draw_view_info.hh
+++ b/source/blender/draw/intern/shaders/draw_view_info.hh
@@ -75,6 +75,16 @@ GPU_SHADER_CREATE_INFO(drw_clipped).define("USE_WORLD_CLIP_PLANES");
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Draw Globals
+ * \{ */
+
+GPU_SHADER_CREATE_INFO(draw_globals)
+ .typedef_source("draw_common_shader_shared.h")
+ .uniform_buf(1, "ObjectMatrices", "drw_globals", Frequency::PASS);
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Geometry Type
* \{ */
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index f18873cc22b..ed40845a47c 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -1292,8 +1292,8 @@ void ANIM_fcurve_equalize_keyframes_loop(FCurve *fcu,
{
uint i;
BezTriple *bezt;
- const float flat_direction_left[2] = {-handle_length, 0.f};
- const float flat_direction_right[2] = {handle_length, 0.f};
+ const float flat_direction_left[2] = {-handle_length, 0.0f};
+ const float flat_direction_right[2] = {handle_length, 0.0f};
/* Loop through an F-Curves keyframes. */
for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 31caa29a02a..7016511111e 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -59,7 +59,7 @@ static void error(const char *str)
struct LaplacianSystem {
LinearSolver *context; /* linear solver */
- int totvert, totface;
+ int verts_num, faces_num;
float **verts; /* vertex coordinates */
float *varea; /* vertex weights for laplacian computation */
@@ -76,8 +76,8 @@ struct LaplacianSystem {
struct HeatWeighting {
const MLoopTri *mlooptri;
const MLoop *mloop; /* needed to find vertices by index */
- int totvert;
- int tottri;
+ int verts_num;
+ int tris_num;
float (*verts)[3]; /* vertex coordinates */
float (*vnors)[3]; /* vertex normals */
@@ -202,28 +202,28 @@ static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int
}
}
-static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totface, int lsq)
+static LaplacianSystem *laplacian_system_construct_begin(int verts_num, int faces_num, int lsq)
{
LaplacianSystem *sys;
sys = MEM_callocN(sizeof(LaplacianSystem), "LaplacianSystem");
- sys->verts = MEM_callocN(sizeof(float *) * totvert, "LaplacianSystemVerts");
- sys->vpinned = MEM_callocN(sizeof(char) * totvert, "LaplacianSystemVpinned");
- sys->faces = MEM_callocN(sizeof(int[3]) * totface, "LaplacianSystemFaces");
+ sys->verts = MEM_callocN(sizeof(float *) * verts_num, "LaplacianSystemVerts");
+ sys->vpinned = MEM_callocN(sizeof(char) * verts_num, "LaplacianSystemVpinned");
+ sys->faces = MEM_callocN(sizeof(int[3]) * faces_num, "LaplacianSystemFaces");
- sys->totvert = 0;
- sys->totface = 0;
+ sys->verts_num = 0;
+ sys->faces_num = 0;
sys->areaweights = 1;
sys->storeweights = 0;
/* create linear solver */
if (lsq) {
- sys->context = EIG_linear_least_squares_solver_new(0, totvert, 1);
+ sys->context = EIG_linear_least_squares_solver_new(0, verts_num, 1);
}
else {
- sys->context = EIG_linear_solver_new(0, totvert, 1);
+ sys->context = EIG_linear_solver_new(0, verts_num, 1);
}
return sys;
@@ -231,42 +231,43 @@ static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totfac
void laplacian_add_vertex(LaplacianSystem *sys, float *co, int pinned)
{
- sys->verts[sys->totvert] = co;
- sys->vpinned[sys->totvert] = pinned;
- sys->totvert++;
+ sys->verts[sys->verts_num] = co;
+ sys->vpinned[sys->verts_num] = pinned;
+ sys->verts_num++;
}
void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3)
{
- sys->faces[sys->totface][0] = v1;
- sys->faces[sys->totface][1] = v2;
- sys->faces[sys->totface][2] = v3;
- sys->totface++;
+ sys->faces[sys->faces_num][0] = v1;
+ sys->faces[sys->faces_num][1] = v2;
+ sys->faces[sys->faces_num][2] = v3;
+ sys->faces_num++;
}
static void laplacian_system_construct_end(LaplacianSystem *sys)
{
int(*face)[3];
- int a, totvert = sys->totvert, totface = sys->totface;
+ int a, verts_num = sys->verts_num, faces_num = sys->faces_num;
laplacian_begin_solve(sys, 0);
- sys->varea = MEM_callocN(sizeof(float) * totvert, "LaplacianSystemVarea");
+ sys->varea = MEM_callocN(sizeof(float) * verts_num, "LaplacianSystemVarea");
- sys->edgehash = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->totface));
- for (a = 0, face = sys->faces; a < sys->totface; a++, face++) {
+ sys->edgehash = BLI_edgehash_new_ex(__func__,
+ BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->faces_num));
+ for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) {
laplacian_increase_edge_count(sys->edgehash, (*face)[0], (*face)[1]);
laplacian_increase_edge_count(sys->edgehash, (*face)[1], (*face)[2]);
laplacian_increase_edge_count(sys->edgehash, (*face)[2], (*face)[0]);
}
if (sys->areaweights) {
- for (a = 0, face = sys->faces; a < sys->totface; a++, face++) {
+ for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) {
laplacian_triangle_area(sys, (*face)[0], (*face)[1], (*face)[2]);
}
}
- for (a = 0; a < totvert; a++) {
+ for (a = 0; a < verts_num; a++) {
if (sys->areaweights) {
if (sys->varea[a] != 0.0f) {
sys->varea[a] = 0.5f / sys->varea[a];
@@ -283,10 +284,10 @@ static void laplacian_system_construct_end(LaplacianSystem *sys)
}
if (sys->storeweights) {
- sys->fweights = MEM_callocN(sizeof(float[3]) * totface, "LaplacianFWeight");
+ sys->fweights = MEM_callocN(sizeof(float[3]) * faces_num, "LaplacianFWeight");
}
- for (a = 0, face = sys->faces; a < totface; a++, face++) {
+ for (a = 0, face = sys->faces; a < faces_num; a++, face++) {
laplacian_triangle_weights(sys, a, (*face)[0], (*face)[1], (*face)[2]);
}
@@ -327,7 +328,7 @@ void laplacian_begin_solve(LaplacianSystem *sys, int index)
if (!sys->variablesdone) {
if (index >= 0) {
- for (a = 0; a < sys->totvert; a++) {
+ for (a = 0; a < sys->verts_num; a++) {
if (sys->vpinned[a]) {
EIG_linear_solver_variable_set(sys->context, 0, a, sys->verts[a][index]);
EIG_linear_solver_variable_lock(sys->context, a);
@@ -411,14 +412,14 @@ static void heat_ray_tree_create(LaplacianSystem *sys)
const MLoopTri *looptri = sys->heat.mlooptri;
const MLoop *mloop = sys->heat.mloop;
float(*verts)[3] = sys->heat.verts;
- int tottri = sys->heat.tottri;
- int totvert = sys->heat.totvert;
+ int tris_num = sys->heat.tris_num;
+ int verts_num = sys->heat.verts_num;
int a;
- sys->heat.bvhtree = BLI_bvhtree_new(tottri, 0.0f, 4, 6);
- sys->heat.vltree = MEM_callocN(sizeof(MLoopTri *) * totvert, "HeatVFaces");
+ sys->heat.bvhtree = BLI_bvhtree_new(tris_num, 0.0f, 4, 6);
+ sys->heat.vltree = MEM_callocN(sizeof(MLoopTri *) * verts_num, "HeatVFaces");
- for (a = 0; a < tottri; a++) {
+ for (a = 0; a < tris_num; a++) {
const MLoopTri *lt = &looptri[a];
float bb[6];
int vtri[3];
@@ -552,9 +553,9 @@ static void heat_calc_vnormals(LaplacianSystem *sys)
float fnor[3];
int a, v1, v2, v3, (*face)[3];
- sys->heat.vnors = MEM_callocN(sizeof(float[3]) * sys->totvert, "HeatVNors");
+ sys->heat.vnors = MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors");
- for (a = 0, face = sys->faces; a < sys->totface; a++, face++) {
+ for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) {
v1 = (*face)[0];
v2 = (*face)[1];
v3 = (*face)[2];
@@ -566,7 +567,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys)
add_v3_v3(sys->heat.vnors[v3], fnor);
}
- for (a = 0; a < sys->totvert; a++) {
+ for (a = 0; a < sys->verts_num; a++) {
normalize_v3(sys->heat.vnors[a]);
}
}
@@ -575,21 +576,21 @@ static void heat_laplacian_create(LaplacianSystem *sys)
{
const MLoopTri *mlooptri = sys->heat.mlooptri, *lt;
const MLoop *mloop = sys->heat.mloop;
- int tottri = sys->heat.tottri;
- int totvert = sys->heat.totvert;
+ int tris_num = sys->heat.tris_num;
+ int verts_num = sys->heat.verts_num;
int a;
/* heat specific definitions */
- sys->heat.mindist = MEM_callocN(sizeof(float) * totvert, "HeatMinDist");
- sys->heat.H = MEM_callocN(sizeof(float) * totvert, "HeatH");
- sys->heat.p = MEM_callocN(sizeof(float) * totvert, "HeatP");
+ sys->heat.mindist = MEM_callocN(sizeof(float) * verts_num, "HeatMinDist");
+ sys->heat.H = MEM_callocN(sizeof(float) * verts_num, "HeatH");
+ sys->heat.p = MEM_callocN(sizeof(float) * verts_num, "HeatP");
/* add verts and faces to laplacian */
- for (a = 0; a < totvert; a++) {
+ for (a = 0; a < verts_num; a++) {
laplacian_add_vertex(sys, sys->heat.verts[a], 0);
}
- for (a = 0, lt = mlooptri; a < tottri; a++, lt++) {
+ for (a = 0, lt = mlooptri; a < tris_num; a++, lt++) {
int vtri[3];
vtri[0] = mloop[lt->tri[0]].v;
vtri[1] = mloop[lt->tri[1]].v;
@@ -600,7 +601,7 @@ static void heat_laplacian_create(LaplacianSystem *sys)
/* for distance computation in set_H */
heat_calc_vnormals(sys);
- for (a = 0; a < totvert; a++) {
+ for (a = 0; a < verts_num; a++) {
heat_set_H(sys, a);
}
}
@@ -648,7 +649,7 @@ void heat_bone_weighting(Object *ob,
MLoop *ml;
float solution, weight;
int *vertsflipped = NULL, *mask = NULL;
- int a, tottri, j, bbone, firstsegment, lastsegment;
+ int a, tris_num, j, bbone, firstsegment, lastsegment;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
MVert *mvert = me->mvert;
@@ -658,7 +659,7 @@ void heat_bone_weighting(Object *ob,
*error_str = NULL;
/* bone heat needs triangulated faces */
- tottri = poly_to_tri_count(me->totpoly, me->totloop);
+ tris_num = poly_to_tri_count(me->totpoly, me->totloop);
/* count triangles and create mask */
if (ob->mode & OB_MODE_WEIGHT_PAINT && (use_face_sel || use_vert_sel)) {
@@ -684,16 +685,16 @@ void heat_bone_weighting(Object *ob,
}
/* create laplacian */
- sys = laplacian_system_construct_begin(me->totvert, tottri, 1);
+ sys = laplacian_system_construct_begin(me->totvert, tris_num, 1);
- sys->heat.tottri = poly_to_tri_count(me->totpoly, me->totloop);
- mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tottri, __func__);
+ sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop);
+ mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__);
BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
sys->heat.mlooptri = mlooptri;
sys->heat.mloop = me->mloop;
- sys->heat.totvert = me->totvert;
+ sys->heat.verts_num = me->totvert;
sys->heat.verts = verts;
sys->heat.root = root;
sys->heat.tip = tip;
@@ -886,7 +887,7 @@ typedef struct MeshDeformBind {
Mesh *cagemesh;
float (*cagecos)[3];
float (*vertexcos)[3];
- int totvert, totcagevert;
+ int verts_num, cage_verts_num;
/* grids */
MemArena *memarena;
@@ -1467,7 +1468,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
}
/* solve for each cage vert */
- for (a = 0; a < mdb->totcagevert; a++) {
+ for (a = 0; a < mdb->cage_verts_num; a++) {
/* fill in right hand side and solve */
for (z = 0; z < mdb->size; z++) {
for (y = 0; y < mdb->size; y++) {
@@ -1503,14 +1504,14 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
if (mdb->weights) {
/* static bind : compute weights for each vertex */
- for (b = 0; b < mdb->totvert; b++) {
+ for (b = 0; b < mdb->verts_num; b++) {
if (mdb->inside[b]) {
copy_v3_v3(vec, mdb->vertexcos[b]);
gridvec[0] = (vec[0] - mdb->min[0] - mdb->halfwidth[0]) / mdb->width[0];
gridvec[1] = (vec[1] - mdb->min[1] - mdb->halfwidth[1]) / mdb->width[1];
gridvec[2] = (vec[2] - mdb->min[2] - mdb->halfwidth[2]) / mdb->width[2];
- mdb->weights[b * mdb->totcagevert + a] = meshdeform_interp_w(mdb, gridvec, vec, a);
+ mdb->weights[b * mdb->cage_verts_num + a] = meshdeform_interp_w(mdb, gridvec, vec, a);
}
}
}
@@ -1536,9 +1537,12 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind
break;
}
- BLI_snprintf(
- message, sizeof(message), "Mesh deform solve %d / %d |||", a + 1, mdb->totcagevert);
- progress_bar((float)(a + 1) / (float)(mdb->totcagevert), message);
+ BLI_snprintf(message,
+ sizeof(message),
+ "Mesh deform solve %d / %d |||",
+ a + 1,
+ mdb->cage_verts_num);
+ progress_bar((float)(a + 1) / (float)(mdb->cage_verts_num), message);
}
#if 0
@@ -1573,7 +1577,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
/* compute bounding box of the cage mesh */
INIT_MINMAX(mdb->min, mdb->max);
- for (a = 0; a < mdb->totcagevert; a++) {
+ for (a = 0; a < mdb->cage_verts_num; a++) {
minmax_v3v3_v3(mdb->min, mdb->max, mdb->cagecos[a]);
}
@@ -1586,13 +1590,14 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect");
mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound");
mdb->bvhtree = BKE_bvhtree_from_mesh_get(&mdb->bvhdata, mdb->cagemesh, BVHTREE_FROM_LOOPTRI, 4);
- mdb->inside = MEM_callocN(sizeof(int) * mdb->totvert, "MDefInside");
+ mdb->inside = MEM_callocN(sizeof(int) * mdb->verts_num, "MDefInside");
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
mdb->dyngrid = MEM_callocN(sizeof(MDefBindInfluence *) * mdb->size3, "MDefDynGrid");
}
else {
- mdb->weights = MEM_callocN(sizeof(float) * mdb->totvert * mdb->totcagevert, "MDefWeights");
+ mdb->weights = MEM_callocN(sizeof(float) * mdb->verts_num * mdb->cage_verts_num,
+ "MDefWeights");
}
mdb->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "harmonic coords arena");
@@ -1632,7 +1637,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
progress_bar(0, "Setting up mesh deform system");
totinside = 0;
- for (a = 0; a < mdb->totvert; a++) {
+ for (a = 0; a < mdb->verts_num; a++) {
copy_v3_v3(vec, mdb->vertexcos[a]);
mdb->inside[a] = meshdeform_inside_cage(mdb, vec);
if (mdb->inside[a]) {
@@ -1674,16 +1679,16 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
/* assign results */
if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) {
- mmd->totinfluence = 0;
+ mmd->influences_num = 0;
for (a = 0; a < mdb->size3; a++) {
for (inf = mdb->dyngrid[a]; inf; inf = inf->next) {
- mmd->totinfluence++;
+ mmd->influences_num++;
}
}
/* convert MDefBindInfluences to smaller MDefInfluences */
mmd->dyngrid = MEM_callocN(sizeof(MDefCell) * mdb->size3, "MDefDynGrid");
- mmd->dyninfluences = MEM_callocN(sizeof(MDefInfluence) * mmd->totinfluence, "MDefInfluence");
+ mmd->dyninfluences = MEM_callocN(sizeof(MDefInfluence) * mmd->influences_num, "MDefInfluence");
offset = 0;
for (a = 0; a < mdb->size3; a++) {
cell = &mmd->dyngrid[a];
@@ -1695,17 +1700,17 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
mdinf->weight = inf->weight;
mdinf->vertex = inf->vertex;
totweight += mdinf->weight;
- cell->totinfluence++;
+ cell->influences_num++;
}
if (totweight > 0.0f) {
mdinf = mmd->dyninfluences + cell->offset;
- for (b = 0; b < cell->totinfluence; b++, mdinf++) {
+ for (b = 0; b < cell->influences_num; b++, mdinf++) {
mdinf->weight /= totweight;
}
}
- offset += cell->totinfluence;
+ offset += cell->influences_num;
}
mmd->dynverts = mdb->inside;
@@ -1732,7 +1737,7 @@ void ED_mesh_deform_bind_callback(Object *object,
MeshDeformModifierData *mmd,
Mesh *cagemesh,
float *vertexcos,
- int totvert,
+ int verts_num,
float cagemat[4][4])
{
MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original(
@@ -1750,19 +1755,19 @@ void ED_mesh_deform_bind_callback(Object *object,
BKE_mesh_wrapper_ensure_mdata(cagemesh);
/* get mesh and cage mesh */
- mdb.vertexcos = MEM_callocN(sizeof(float[3]) * totvert, "MeshDeformCos");
- mdb.totvert = totvert;
+ mdb.vertexcos = MEM_callocN(sizeof(float[3]) * verts_num, "MeshDeformCos");
+ mdb.verts_num = verts_num;
mdb.cagemesh = cagemesh;
- mdb.totcagevert = mdb.cagemesh->totvert;
- mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.totcagevert, "MeshDeformBindCos");
+ mdb.cage_verts_num = mdb.cagemesh->totvert;
+ mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos");
copy_m4_m4(mdb.cagemat, cagemat);
mvert = mdb.cagemesh->mvert;
- for (a = 0; a < mdb.totcagevert; a++) {
+ for (a = 0; a < mdb.cage_verts_num; a++) {
copy_v3_v3(mdb.cagecos[a], mvert[a].co);
}
- for (a = 0; a < mdb.totvert; a++) {
+ for (a = 0; a < mdb.verts_num; a++) {
mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3);
}
@@ -1771,12 +1776,12 @@ void ED_mesh_deform_bind_callback(Object *object,
/* assign bind variables */
mmd_orig->bindcagecos = (float *)mdb.cagecos;
- mmd_orig->totvert = mdb.totvert;
- mmd_orig->totcagevert = mdb.totcagevert;
+ mmd_orig->verts_num = mdb.verts_num;
+ mmd_orig->cage_verts_num = mdb.cage_verts_num;
copy_m4_m4(mmd_orig->bindmat, mmd_orig->object->obmat);
/* transform bindcagecos to world space */
- for (a = 0; a < mdb.totcagevert; a++) {
+ for (a = 0; a < mdb.cage_verts_num; a++) {
mul_m4_v3(mmd_orig->object->obmat, mmd_orig->bindcagecos + a * 3);
}
diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc
index 49c4002eee8..3cc3638c299 100644
--- a/source/blender/editors/asset/intern/asset_indexer.cc
+++ b/source/blender/editors/asset/intern/asset_indexer.cc
@@ -39,7 +39,6 @@ using namespace blender::bke;
using namespace blender::bke::idprop;
/**
- * \file asset_indexer.cc
* \brief Indexer for asset libraries.
*
* Indexes are stored per input file. Each index can contain zero to multiple asset entries.
@@ -494,15 +493,15 @@ struct AssetLibraryIndex {
return;
}
struct direntry *dir_entries = nullptr;
- int num_entries = BLI_filelist_dir_contents(index_path, &dir_entries);
- for (int i = 0; i < num_entries; i++) {
+ const int dir_entries_num = BLI_filelist_dir_contents(index_path, &dir_entries);
+ for (int i = 0; i < dir_entries_num; i++) {
struct direntry *entry = &dir_entries[i];
if (BLI_str_endswith(entry->relname, ".index.json")) {
unused_file_indices.add_as(std::string(entry->path));
}
}
- BLI_filelist_free(dir_entries, num_entries);
+ BLI_filelist_free(dir_entries, dir_entries_num);
}
void mark_as_used(const std::string &filename)
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 5ff63e767f6..38c14391273 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1209,7 +1209,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
old_to_new_map = init_index_map(obedit, &old_totvert);
}
- for (i = j = 0; i < hmd->totindex; i++) {
+ for (i = j = 0; i < hmd->indexar_num; i++) {
if (hmd->indexar[i] < old_totvert) {
index = old_to_new_map[hmd->indexar[i]];
if (index != -1) {
@@ -1221,7 +1221,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
}
}
- hmd->totindex = j;
+ hmd->indexar_num = j;
}
}
}
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 0afb1c2f4af..611dbb2e80c 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -526,16 +526,16 @@ static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
/** \name Paste From File Operator
* \{ */
-static int paste_from_file(bContext *C, ReportList *reports, const char *filename)
+static int paste_from_file(bContext *C, ReportList *reports, const char *filepath)
{
Object *obedit = CTX_data_edit_object(C);
char *strp;
size_t filelen;
int retval;
- strp = BLI_file_read_text_as_mem(filename, 1, &filelen);
+ strp = BLI_file_read_text_as_mem(filepath, 1, &filelen);
if (strp == NULL) {
- BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filename);
+ BKE_reportf(reports, RPT_ERROR, "Failed to open file '%s'", filepath);
return OPERATOR_CANCELLED;
}
strp[filelen] = 0;
@@ -545,7 +545,7 @@ static int paste_from_file(bContext *C, ReportList *reports, const char *filenam
retval = OPERATOR_FINISHED;
}
else {
- BKE_reportf(reports, RPT_ERROR, "File too long %s", filename);
+ BKE_reportf(reports, RPT_ERROR, "File too long %s", filepath);
retval = OPERATOR_CANCELLED;
}
@@ -556,12 +556,12 @@ static int paste_from_file(bContext *C, ReportList *reports, const char *filenam
static int paste_from_file_exec(bContext *C, wmOperator *op)
{
- char *path;
+ char *filepath;
int retval;
- path = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0, NULL);
- retval = paste_from_file(C, op->reports, path);
- MEM_freeN(path);
+ filepath = RNA_string_get_alloc(op->ptr, "filepath", NULL, 0, NULL);
+ retval = paste_from_file(C, op->reports, filepath);
+ MEM_freeN(filepath);
return retval;
}
@@ -2091,7 +2091,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
VFont *vfont = NULL;
- const char *path;
+ const char *filepath;
PointerRNA idptr;
PropertyPointerRNA *pprop;
@@ -2106,13 +2106,13 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)
vfont = (VFont *)idptr.owner_id;
}
- path = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir;
+ filepath = (vfont && !BKE_vfont_is_builtin(vfont)) ? vfont->filepath : U.fontdir;
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return font_open_exec(C, op);
}
- RNA_string_set(op->ptr, "filepath", path);
+ RNA_string_set(op->ptr, "filepath", filepath);
WM_event_add_fileselect(C, op);
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc
index 9cde23451dc..17108619a4d 100644
--- a/source/blender/editors/curves/intern/curves_add.cc
+++ b/source/blender/editors/curves/intern/curves_add.cc
@@ -21,7 +21,7 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi
float *radius_data = (float *)CustomData_add_layer_named(
&curves.point_data, CD_PROP_FLOAT, CD_DEFAULT, nullptr, curves.point_size, "radius");
- MutableSpan<float> radii{radius_data, curves.points_size()};
+ MutableSpan<float> radii{radius_data, curves.points_num()};
for (const int i : offsets.index_range()) {
offsets[i] = points_per_curve * i;
@@ -30,7 +30,7 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi
RandomNumberGenerator rng;
for (const int i : curves.curves_range()) {
- const IndexRange curve_range = curves.range_for_curve(i);
+ const IndexRange curve_range = curves.points_for_curve(i);
MutableSpan<float3> curve_positions = positions.slice(curve_range);
MutableSpan<float> curve_radii = radii.slice(curve_range);
diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt
index f8fa23a54d1..09a3cac0d48 100644
--- a/source/blender/editors/gpencil/CMakeLists.txt
+++ b/source/blender/editors/gpencil/CMakeLists.txt
@@ -28,7 +28,7 @@ set(SRC
gpencil_add_monkey.c
gpencil_add_stroke.c
gpencil_armature.c
- gpencil_bake_animation.c
+ gpencil_bake_animation.cc
gpencil_convert.c
gpencil_data.c
gpencil_edit.c
@@ -36,7 +36,7 @@ set(SRC
gpencil_fill.c
gpencil_interpolate.c
gpencil_merge.c
- gpencil_mesh.c
+ gpencil_mesh.cc
gpencil_ops.c
gpencil_ops_versioning.c
gpencil_paint.c
diff --git a/source/blender/editors/gpencil/gpencil_bake_animation.c b/source/blender/editors/gpencil/gpencil_bake_animation.cc
index 5d33377900f..0667da46e25 100644
--- a/source/blender/editors/gpencil/gpencil_bake_animation.c
+++ b/source/blender/editors/gpencil/gpencil_bake_animation.cc
@@ -61,7 +61,7 @@ const EnumPropertyItem rna_gpencil_reproject_type_items[] = {
0,
"Cursor",
"Reproject the strokes using the orientation of 3D cursor"},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
/* Check frame_end is always > start frame! */
@@ -86,7 +86,7 @@ static bool gpencil_bake_grease_pencil_animation_poll(bContext *C)
}
/* Check if grease pencil or empty for dupli groups. */
- if ((obact == NULL) || (!ELEM(obact->type, OB_GPENCIL, OB_EMPTY))) {
+ if ((obact == nullptr) || (!ELEM(obact->type, OB_GPENCIL, OB_EMPTY))) {
return false;
}
@@ -95,10 +95,10 @@ static bool gpencil_bake_grease_pencil_animation_poll(bContext *C)
return (area && area->spacetype);
}
-typedef struct GpBakeOb {
+struct GpBakeOb {
struct GpBakeOb *next, *prev;
Object *ob;
-} GpBakeOb;
+};
/* Get list of keyframes used by selected objects. */
static void animdata_keyframe_list_get(ListBase *ob_list,
@@ -109,7 +109,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) {
Object *ob = elem->ob;
AnimData *adt = BKE_animdata_from_id(&ob->id);
- if ((adt == NULL) || (adt->action == NULL)) {
+ if ((adt == nullptr) || (adt->action == nullptr)) {
continue;
}
LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
@@ -131,16 +131,15 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
{
- GpBakeOb *elem = NULL;
+ GpBakeOb *elem = nullptr;
ListBase *lb;
- DupliObject *dob;
lb = object_duplilist(depsgraph, scene, ob);
- for (dob = lb->first; dob; dob = dob->next) {
+ LISTBASE_FOREACH (DupliObject *, dob, lb) {
if (dob->ob->type != OB_GPENCIL) {
continue;
}
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = dob->ob;
BLI_addtail(list, elem);
}
@@ -150,13 +149,13 @@ static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *o
static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
{
- GpBakeOb *elem = NULL;
+ GpBakeOb *elem = nullptr;
/* Add active object. In some files this could not be in selected array. */
Object *obact = CTX_data_active_object(C);
if (obact->type == OB_GPENCIL) {
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = obact;
BLI_addtail(list, elem);
}
@@ -172,7 +171,7 @@ static void gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene
}
/* Add selected objects. */
if (ob->type == OB_GPENCIL) {
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = ob;
BLI_addtail(list, elem);
}
@@ -199,7 +198,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
- ListBase ob_selected_list = {NULL, NULL};
+ ListBase ob_selected_list = {nullptr, nullptr};
gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
/* Grab all relevant settings. */
@@ -215,10 +214,11 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
- const int project_type = RNA_enum_get(op->ptr, "project_type");
+ const eGP_ReprojectModes project_type = (eGP_ReprojectModes)RNA_enum_get(op->ptr,
+ "project_type");
/* Create a new grease pencil object. */
- Object *ob_gpencil = NULL;
+ Object *ob_gpencil = nullptr;
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
ob_gpencil = ED_gpencil_add_object(C, scene->cursor.location, local_view_bits);
float invmat[4][4];
@@ -230,8 +230,8 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
/* Set cursor to indicate working. */
WM_cursor_wait(true);
- GP_SpaceConversion gsc = {NULL};
- SnapObjectContext *sctx = NULL;
+ GP_SpaceConversion gsc = {nullptr};
+ SnapObjectContext *sctx = nullptr;
if (project_type != GP_REPROJECT_KEEP) {
/* Init space conversion stuff. */
gpencil_point_conversion_init(C, &gsc);
@@ -271,14 +271,14 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
/* Loop all objects in the list. */
LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) {
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob);
- bGPdata *gpd_src = ob_eval->data;
+ bGPdata *gpd_src = static_cast<bGPdata *>(ob_eval->data);
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
/* Create destination layer. */
char *layer_name;
layer_name = BLI_sprintfN("%s_%s", elem->ob->id.name + 2, gpl_src->info);
bGPDlayer *gpl_dst = BKE_gpencil_layer_named_get(gpd_dst, layer_name);
- if (gpl_dst == NULL) {
+ if (gpl_dst == nullptr) {
gpl_dst = BKE_gpencil_layer_addnew(gpd_dst, layer_name, true, false);
}
MEM_freeN(layer_name);
@@ -293,7 +293,7 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
/* Duplicate frame. */
bGPDframe *gpf_src = BKE_gpencil_layer_frame_get(
gpl_src, remap_cfra, GP_GETFRAME_USE_PREV);
- if (gpf_src == NULL) {
+ if (gpf_src == nullptr) {
continue;
}
bGPDframe *gpf_dst = BKE_gpencil_frame_duplicate(gpf_src, true);
@@ -346,19 +346,19 @@ static int gpencil_bake_grease_pencil_animation_exec(bContext *C, wmOperator *op
/* Free memory. */
gpencil_bake_free_ob_list(&ob_selected_list);
- if (sctx != NULL) {
+ if (sctx != nullptr) {
ED_transform_snap_object_context_destroy(sctx);
}
/* Free temp hash table. */
- if (keyframe_list != NULL) {
- BLI_ghash_free(keyframe_list, NULL, NULL);
+ if (keyframe_list != nullptr) {
+ BLI_ghash_free(keyframe_list, nullptr, nullptr);
}
/* Notifiers. */
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
DEG_id_tag_update(&gpd_dst->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, nullptr);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
/* Reset cursor. */
@@ -418,12 +418,15 @@ void GPENCIL_OT_bake_grease_pencil_animation(wmOperatorType *ot)
prop = RNA_def_int(
ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000);
- RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end);
+ RNA_def_property_update_runtime(prop, (void *)gpencil_bake_set_frame_end);
prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
- RNA_def_boolean(
- ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes");
+ RNA_def_boolean(ot->srna,
+ "only_selected",
+ false,
+ "Only Selected Keyframes",
+ "Convert only selected keyframes");
RNA_def_int(
ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000);
diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c
index d4518f21586..4f9468cc9c4 100644
--- a/source/blender/editors/gpencil/gpencil_convert.c
+++ b/source/blender/editors/gpencil/gpencil_convert.c
@@ -207,7 +207,7 @@ typedef struct tGpTimingData {
int seed;
/* Data set from points, used to compute final timing FCurve */
- int num_points, cur_point;
+ int points_num, cur_point;
/* Distances */
float *dists;
@@ -229,29 +229,29 @@ typedef struct tGpTimingData {
/* Init point buffers for timing data.
* Note this assumes we only grow those arrays!
*/
-static void gpencil_timing_data_set_nbr(tGpTimingData *gtd, const int nbr)
+static void gpencil_timing_data_set_num(tGpTimingData *gtd, const int num)
{
float *tmp;
- BLI_assert(nbr > gtd->num_points);
+ BLI_assert(num > gtd->points_num);
/* distances */
tmp = gtd->dists;
- gtd->dists = MEM_callocN(sizeof(float) * nbr, __func__);
+ gtd->dists = MEM_callocN(sizeof(float) * num, __func__);
if (tmp) {
- memcpy(gtd->dists, tmp, sizeof(float) * gtd->num_points);
+ memcpy(gtd->dists, tmp, sizeof(float) * gtd->points_num);
MEM_freeN(tmp);
}
/* times */
tmp = gtd->times;
- gtd->times = MEM_callocN(sizeof(float) * nbr, __func__);
+ gtd->times = MEM_callocN(sizeof(float) * num, __func__);
if (tmp) {
- memcpy(gtd->times, tmp, sizeof(float) * gtd->num_points);
+ memcpy(gtd->times, tmp, sizeof(float) * gtd->points_num);
MEM_freeN(tmp);
}
- gtd->num_points = nbr;
+ gtd->points_num = num;
}
/* add stroke point to timing buffers */
@@ -297,15 +297,15 @@ static void gpencil_timing_data_add_point(tGpTimingData *gtd,
static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
RNG *rng,
const int idx,
- const int nbr_gaps,
- int *nbr_done_gaps,
+ const int gaps_count,
+ int *gaps_done_count,
const float tot_gaps_time,
const float delta_time,
float *next_delta_time)
{
int j;
- for (j = idx + 1; j < gtd->num_points; j++) {
+ for (j = idx + 1; j < gtd->points_num; j++) {
if (gtd->times[j] < 0) {
gtd->times[j] = -gtd->times[j];
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
@@ -316,7 +316,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
/* We want gaps that are in gtd->gap_duration +/- gtd->gap_randomness range,
* and which sum to exactly tot_gaps_time...
*/
- int rem_gaps = nbr_gaps - (*nbr_done_gaps);
+ int rem_gaps = gaps_count - (*gaps_done_count);
if (rem_gaps < 2) {
/* Last gap, just give remaining time! */
*next_delta_time = tot_gaps_time;
@@ -327,7 +327,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
/* This code ensures that if the first gaps
* have been shorter than average gap_duration, next gaps
* will tend to be longer (i.e. try to recover the lateness), and vice-versa! */
- delta = delta_time - (gtd->gap_duration * (*nbr_done_gaps));
+ delta = delta_time - (gtd->gap_duration * (*gaps_done_count));
/* Clamp min between [-gap_randomness, 0.0], with lower delta giving higher min */
min = -gtd->gap_randomness - delta;
@@ -343,7 +343,7 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
*next_delta_time += gtd->gap_duration;
}
}
- (*nbr_done_gaps)++;
+ (*gaps_done_count)++;
break;
}
}
@@ -353,14 +353,14 @@ static int gpencil_find_end_of_stroke_idx(tGpTimingData *gtd,
static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
RNG *rng,
- int *nbr_gaps,
+ int *gaps_count,
float *r_tot_gaps_time)
{
float delta_time = 0.0f;
- for (int i = 0; i < gtd->num_points; i++) {
+ for (int i = 0; i < gtd->points_num; i++) {
if (gtd->times[i] < 0 && i) {
- (*nbr_gaps)++;
+ (*gaps_count)++;
gtd->times[i] = -gtd->times[i] - delta_time;
delta_time += gtd->times[i] - gtd->times[i - 1];
gtd->times[i] = -gtd->times[i - 1]; /* Temp marker, values *have* to be different! */
@@ -371,7 +371,7 @@ static void gpencil_stroke_path_animation_preprocess_gaps(tGpTimingData *gtd,
}
gtd->tot_time -= delta_time;
- *r_tot_gaps_time = (float)(*nbr_gaps) * gtd->gap_duration;
+ *r_tot_gaps_time = (float)(*gaps_count) * gtd->gap_duration;
gtd->tot_time += *r_tot_gaps_time;
if (gtd->gap_randomness > 0.0f) {
BLI_rng_srandom(rng, gtd->seed);
@@ -387,7 +387,7 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
tGpTimingData *gtd,
RNG *rng,
const float time_range,
- const int nbr_gaps,
+ const int gaps_count,
const float tot_gaps_time)
{
/* Use actual recorded timing! */
@@ -399,20 +399,20 @@ static void gpencil_stroke_path_animation_add_keyframes(ReportList *reports,
/* CustomGaps specific */
float delta_time = 0.0f, next_delta_time = 0.0f;
- int nbr_done_gaps = 0;
+ int gaps_done_count = 0;
/* This is a bit tricky, as:
* - We can't add arbitrarily close points on FCurve (in time).
* - We *must* have all "caps" points of all strokes in FCurve, as much as possible!
*/
- for (int i = 0; i < gtd->num_points; i++) {
+ for (int i = 0; i < gtd->points_num; i++) {
/* If new stroke... */
if (i > end_stroke_idx) {
start_stroke_idx = i;
delta_time = next_delta_time;
/* find end of that new stroke */
end_stroke_idx = gpencil_find_end_of_stroke_idx(
- gtd, rng, i, nbr_gaps, &nbr_done_gaps, tot_gaps_time, delta_time, &next_delta_time);
+ gtd, rng, i, gaps_count, &gaps_done_count, tot_gaps_time, delta_time, &next_delta_time);
/* This one should *never* be negative! */
end_stroke_time = time_start +
((gtd->times[end_stroke_idx] + delta_time) / gtd->tot_time * time_range);
@@ -502,7 +502,7 @@ static void gpencil_stroke_path_animation(bContext *C,
FCurve *fcu;
PointerRNA ptr;
PropertyRNA *prop = NULL;
- int nbr_gaps = 0;
+ int gaps_count = 0;
if (gtd->mode == GP_STROKECONVERT_TIMING_NONE) {
return;
@@ -571,7 +571,7 @@ static void gpencil_stroke_path_animation(bContext *C,
/* Pre-process gaps, in case we don't want to keep their original timing */
if (gtd->mode == GP_STROKECONVERT_TIMING_CUSTOMGAP) {
- gpencil_stroke_path_animation_preprocess_gaps(gtd, rng, &nbr_gaps, &tot_gaps_time);
+ gpencil_stroke_path_animation_preprocess_gaps(gtd, rng, &gaps_count, &tot_gaps_time);
}
if (gtd->realtime) {
@@ -582,7 +582,7 @@ static void gpencil_stroke_path_animation(bContext *C,
}
gpencil_stroke_path_animation_add_keyframes(
- reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, nbr_gaps, tot_gaps_time);
+ reports, ptr, prop, depsgraph, fcu, cu, gtd, rng, time_range, gaps_count, tot_gaps_time);
BLI_rng_free(rng);
}
@@ -684,7 +684,7 @@ static void gpencil_stroke_to_path(bContext *C,
}
if (do_gtd) {
- gpencil_timing_data_set_nbr(gtd, nu->pntsu);
+ gpencil_timing_data_set_num(gtd, nu->pntsu);
}
/* If needed, make the link between both strokes with two zero-radius additional points */
@@ -929,7 +929,7 @@ static void gpencil_stroke_to_bezier(bContext *C,
}
if (do_gtd) {
- gpencil_timing_data_set_nbr(gtd, nu->pntsu);
+ gpencil_timing_data_set_num(gtd, nu->pntsu);
}
tot = gps->totpoints;
@@ -1536,7 +1536,7 @@ static int gpencil_convert_layer_exec(bContext *C, wmOperator *op)
gtd.gap_randomness = RNA_float_get(op->ptr, "gap_randomness");
gtd.gap_randomness = min_ff(gtd.gap_randomness, gtd.gap_duration);
gtd.seed = RNA_int_get(op->ptr, "seed");
- gtd.num_points = gtd.cur_point = 0;
+ gtd.points_num = gtd.cur_point = 0;
gtd.dists = gtd.times = NULL;
gtd.tot_dist = gtd.tot_time = gtd.gap_tot_time = 0.0f;
gtd.inittime = 0.0;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 8506e90191f..a8fb344f366 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3924,31 +3924,36 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) {
if (gps->flag & GP_STROKE_SELECT) {
- for (int r = 0; r < repeat; r++) {
+ /* TODO use `BKE_gpencil_stroke_smooth` when the weights are better used. */
+ bGPDstroke gps_old = *gps;
+ gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points);
+ /* Here the iteration needs to be done outside the smooth functions,
+ * as there are points that don't get smoothed. */
+ for (int n = 0; n < repeat; n++) {
for (int i = 0; i < gps->totpoints; i++) {
- bGPDspoint *pt = &gps->points[i];
- if ((only_selected) && ((pt->flag & GP_SPOINT_SELECT) == 0)) {
+ if (only_selected && (gps->points[i].flag & GP_SPOINT_SELECT) == 0) {
continue;
}
- /* perform smoothing */
+ /* Perform smoothing. */
if (smooth_position) {
- BKE_gpencil_stroke_smooth_point(gps, i, factor, false);
+ BKE_gpencil_stroke_smooth_point(&gps_old, i, factor, 1, false, false, gps);
}
if (smooth_strength) {
- BKE_gpencil_stroke_smooth_strength(gps, i, factor);
+ BKE_gpencil_stroke_smooth_strength(&gps_old, i, factor, 1, gps);
}
if (smooth_thickness) {
- /* thickness need to repeat process several times */
- for (int r2 = 0; r2 < repeat * 2; r2++) {
- BKE_gpencil_stroke_smooth_thickness(gps, i, 1.0f - factor);
- }
+ BKE_gpencil_stroke_smooth_thickness(&gps_old, i, 1.0f - factor, 1, gps);
}
if (smooth_uv) {
- BKE_gpencil_stroke_smooth_uv(gps, i, factor);
+ BKE_gpencil_stroke_smooth_uv(&gps_old, i, factor, 1, gps);
}
}
+ if (n < repeat - 1) {
+ memcpy(gps_old.points, gps->points, sizeof(bGPDspoint) * gps->totpoints);
+ }
}
+ MEM_freeN(gps_old.points);
}
}
GP_EDITABLE_STROKES_END(gpstroke_iter);
@@ -4926,10 +4931,10 @@ void GPENCIL_OT_stroke_smooth(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
- prop = RNA_def_int(ot->srna, "repeat", 1, 1, 50, "Repeat", "", 1, 20);
+ prop = RNA_def_int(ot->srna, "repeat", 2, 1, 1000, "Repeat", "", 1, 1000);
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- RNA_def_float(ot->srna, "factor", 0.5f, 0.0f, 2.0f, "Factor", "", 0.0f, 2.0f);
+ RNA_def_float(ot->srna, "factor", 1.0f, 0.0f, 2.0f, "Factor", "", 0.0f, 1.0f);
RNA_def_boolean(ot->srna,
"only_selected",
true,
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 45a2247c65e..94acf464691 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -1638,14 +1638,9 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
}
}
- /* smooth stroke */
- float reduce = 0.0f;
- float smoothfac = 1.0f;
- for (int r = 0; r < 1; r++) {
- for (int i = 0; i < gps->totpoints; i++) {
- BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce, false);
- }
- reduce += 0.25f; /* reduce the factor */
+ /* Smooth stroke. No copy of the stroke since there only a minor improvement here. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ BKE_gpencil_stroke_smooth_point(gps, i, 1.0f, 2, false, true, gps);
}
/* if axis locked, reproject to plane locked */
@@ -2113,18 +2108,18 @@ static bool gpencil_do_frame_fill(tGPDfill *tgpf, const bool is_inverted)
int totpoints_prv = 0;
int loop_limit = 0;
while (totpoints > 0) {
- /* analyze outline */
+ /* Analyze outline. */
gpencil_get_outline_points(tgpf, (totpoints == 1) ? true : false);
- /* create array of points from stack */
+ /* Create array of points from stack. */
totpoints = gpencil_points_from_stack(tgpf);
+ if (totpoints > 0) {
+ /* Create z-depth array for reproject. */
+ gpencil_get_depth_array(tgpf);
- /* create z-depth array for reproject */
- gpencil_get_depth_array(tgpf);
-
- /* create stroke and reproject */
- gpencil_stroke_from_buffer(tgpf);
-
+ /* Create stroke and reproject. */
+ gpencil_stroke_from_buffer(tgpf);
+ }
if (is_inverted) {
gpencil_erase_processed_area(tgpf);
}
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 1bb98ce51c7..56c94e4494d 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -13,6 +13,10 @@
#define DEPTH_INVALID 1.0f
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* internal exports only */
struct Material;
struct bGPDspoint;
@@ -826,3 +830,7 @@ struct GP_EditableStrokes_Iter {
extern const EnumPropertyItem rna_gpencil_reproject_type_items[];
/* ****************************************************** */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index 65060e1bab5..8630b7f23d4 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -310,23 +310,6 @@ static void gpencil_stroke_pair_table(bContext *C,
}
}
-static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps,
- float smooth_factor,
- int smooth_steps)
-{
- if (smooth_factor == 0.0f) {
- return;
- }
-
- float reduce = 0.0f;
- for (int r = 0; r < smooth_steps; r++) {
- for (int i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce, false);
- BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor);
- }
- reduce += 0.25f; /* reduce the factor */
- }
-}
/* Perform interpolation */
static void gpencil_interpolate_update_points(const bGPDstroke *gps_from,
const bGPDstroke *gps_to,
@@ -553,7 +536,15 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi)
/* Update points position. */
gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, tgpil->factor);
- gpencil_interpolate_smooth_stroke(new_stroke, tgpi->smooth_factor, tgpi->smooth_steps);
+ BKE_gpencil_stroke_smooth(new_stroke,
+ tgpi->smooth_factor,
+ tgpi->smooth_steps,
+ true,
+ true,
+ false,
+ false,
+ true,
+ NULL);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, new_stroke);
@@ -1385,7 +1376,8 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op)
/* Update points position. */
gpencil_interpolate_update_points(gps_from, gps_to, new_stroke, factor);
- gpencil_interpolate_smooth_stroke(new_stroke, smooth_factor, smooth_steps);
+ BKE_gpencil_stroke_smooth(
+ new_stroke, smooth_factor, smooth_steps, true, true, false, false, true, NULL);
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gpd, new_stroke);
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.cc
index 7db55796053..aee00d4ede3 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.cc
@@ -67,10 +67,10 @@ static bool gpencil_bake_mesh_animation_poll(bContext *C)
return (area && area->spacetype);
}
-typedef struct GpBakeOb {
+struct GpBakeOb {
struct GpBakeOb *next, *prev;
Object *ob;
-} GpBakeOb;
+};
/* Get list of keyframes used by selected objects. */
static void animdata_keyframe_list_get(ListBase *ob_list,
@@ -81,7 +81,7 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) {
Object *ob = elem->ob;
AnimData *adt = BKE_animdata_from_id(&ob->id);
- if ((adt == NULL) || (adt->action == NULL)) {
+ if ((adt == nullptr) || (adt->action == nullptr)) {
continue;
}
LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) {
@@ -103,15 +103,14 @@ static void animdata_keyframe_list_get(ListBase *ob_list,
static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list)
{
- GpBakeOb *elem = NULL;
+ GpBakeOb *elem = nullptr;
ListBase *lb;
- DupliObject *dob;
lb = object_duplilist(depsgraph, scene, ob);
- for (dob = lb->first; dob; dob = dob->next) {
+ LISTBASE_FOREACH (DupliObject *, dob, lb) {
if (dob->ob->type != OB_MESH) {
continue;
}
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = dob->ob;
BLI_addtail(list, elem);
}
@@ -121,17 +120,17 @@ static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *o
static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene, ListBase *list)
{
- GpBakeOb *elem = NULL;
+ GpBakeOb *elem = nullptr;
bool simple_material = false;
/* Add active object. In some files this could not be in selected array. */
Object *obact = CTX_data_active_object(C);
- if (obact == NULL) {
+ if (obact == nullptr) {
return false;
}
if (obact->type == OB_MESH) {
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = obact;
BLI_addtail(list, elem);
}
@@ -148,7 +147,7 @@ static bool gpencil_bake_ob_list(bContext *C, Depsgraph *depsgraph, Scene *scene
}
/* Add selected meshes. */
if (ob->type == OB_MESH) {
- elem = MEM_callocN(sizeof(GpBakeOb), __func__);
+ elem = MEM_cnew<GpBakeOb>(__func__);
elem->ob = ob;
BLI_addtail(list, elem);
}
@@ -177,11 +176,11 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
- ListBase ob_selected_list = {NULL, NULL};
+ ListBase ob_selected_list = {nullptr, nullptr};
gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list);
/* Cannot check this in poll because the active object changes. */
- if (ob_selected_list.first == NULL) {
+ if (ob_selected_list.first == nullptr) {
BKE_report(op->reports, RPT_INFO, "No valid object selected");
gpencil_bake_free_ob_list(&ob_selected_list);
return OPERATOR_CANCELLED;
@@ -205,28 +204,29 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
const bool only_selected = RNA_boolean_get(op->ptr, "only_selected");
const float offset = RNA_float_get(op->ptr, "offset");
const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start;
- const int project_type = RNA_enum_get(op->ptr, "project_type");
- eGP_TargetObjectMode target = RNA_enum_get(op->ptr, "target");
+ const eGP_ReprojectModes project_type = (eGP_ReprojectModes)RNA_enum_get(op->ptr,
+ "project_type");
+ const eGP_TargetObjectMode target = (eGP_TargetObjectMode)RNA_enum_get(op->ptr, "target");
/* Create a new grease pencil object in origin or reuse selected. */
- Object *ob_gpencil = NULL;
+ Object *ob_gpencil = nullptr;
bool newob = false;
if (target == GP_TARGET_OB_SELECTED) {
ob_gpencil = BKE_view_layer_non_active_selected_object(CTX_data_view_layer(C), v3d);
- if (ob_gpencil != NULL) {
+ if (ob_gpencil != nullptr) {
if (ob_gpencil->type != OB_GPENCIL) {
BKE_report(op->reports, RPT_WARNING, "Target object not a grease pencil, ignoring!");
- ob_gpencil = NULL;
+ ob_gpencil = nullptr;
}
else if (BKE_object_obdata_is_libdata(ob_gpencil)) {
BKE_report(op->reports, RPT_WARNING, "Target object library-data, ignoring!");
- ob_gpencil = NULL;
+ ob_gpencil = nullptr;
}
}
}
- if (ob_gpencil == NULL) {
+ if (ob_gpencil == nullptr) {
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
const float loc[3] = {0.0f, 0.0f, 0.0f};
ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
@@ -239,8 +239,8 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Set cursor to indicate working. */
WM_cursor_wait(true);
- GP_SpaceConversion gsc = {NULL};
- SnapObjectContext *sctx = NULL;
+ GP_SpaceConversion gsc = {nullptr};
+ SnapObjectContext *sctx = nullptr;
if (project_type != GP_REPROJECT_KEEP) {
/* Init space conversion stuff. */
gpencil_point_conversion_init(C, &gsc);
@@ -309,7 +309,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
if (project_type != GP_REPROJECT_KEEP) {
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
bGPDframe *gpf = gpl->actframe;
- if (gpf == NULL) {
+ if (gpf == nullptr) {
continue;
}
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
@@ -355,12 +355,12 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
/* Free memory. */
gpencil_bake_free_ob_list(&ob_selected_list);
- if (sctx != NULL) {
+ if (sctx != nullptr) {
ED_transform_snap_object_context_destroy(sctx);
}
/* Free temp hash table. */
- if (keyframe_list != NULL) {
- BLI_ghash_free(keyframe_list, NULL, NULL);
+ if (keyframe_list != nullptr) {
+ BLI_ghash_free(keyframe_list, nullptr, nullptr);
}
/* notifiers */
@@ -368,7 +368,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
DEG_relations_tag_update(bmain);
}
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL);
+ WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, nullptr);
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
/* Reset cursor. */
@@ -392,7 +392,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
static const EnumPropertyItem target_object_modes[] = {
{GP_TARGET_OB_NEW, "NEW", 0, "New Object", ""},
{GP_TARGET_OB_SELECTED, "SELECTED", 0, "Selected Object", ""},
- {0, NULL, 0, NULL, NULL},
+ {0, nullptr, 0, nullptr, nullptr},
};
PropertyRNA *prop;
@@ -424,7 +424,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
prop = RNA_def_int(
ot->srna, "frame_end", 250, 1, 100000, "End Frame", "The end frame of animation", 1, 100000);
- RNA_def_property_update_runtime(prop, gpencil_bake_set_frame_end);
+ RNA_def_property_update_runtime(prop, (void *)gpencil_bake_set_frame_end);
prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100);
@@ -433,7 +433,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
prop = RNA_def_float_rotation(ot->srna,
"angle",
0,
- NULL,
+ nullptr,
DEG2RADF(0.0f),
DEG2RADF(180.0f),
"Threshold Angle",
@@ -452,10 +452,13 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot)
0.0,
100.00);
- RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges");
- RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes");
- RNA_def_boolean(
- ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes");
+ RNA_def_boolean(ot->srna, "seams", false, "Only Seam Edges", "Convert only seam edges");
+ RNA_def_boolean(ot->srna, "faces", true, "Export Faces", "Export faces as filled strokes");
+ RNA_def_boolean(ot->srna,
+ "only_selected",
+ false,
+ "Only Selected Keyframes",
+ "Convert only selected keyframes");
RNA_def_int(
ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000);
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 18dc8d4bc72..93a4a784674 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1197,29 +1197,21 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
gpencil_subdivide_stroke(gpd, gps, subdivide);
}
- /* Smooth stroke after subdiv - only if there's something to do for each iteration,
- * the factor is reduced to get a better smoothing
- * without changing too much the original stroke. */
- if ((brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) &&
- (brush->gpencil_settings->draw_smoothfac > 0.0f)) {
- float reduce = 0.0f;
- for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) {
- for (i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth_point(
- gps, i, brush->gpencil_settings->draw_smoothfac - reduce, false);
- BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac);
- }
- reduce += 0.25f; /* reduce the factor */
- }
+ /* Smooth stroke after subdiv - only if there's something to do for each iteration.
+ * Keep the original stroke shape as much as possible. */
+ const float smoothfac = brush->gpencil_settings->draw_smoothfac;
+ const int iterations = brush->gpencil_settings->draw_smoothlvl;
+ if (brush->gpencil_settings->flag & GP_BRUSH_GROUP_SETTINGS) {
+ BKE_gpencil_stroke_smooth(gps, smoothfac, iterations, true, true, false, false, true, NULL);
}
/* If reproject the stroke using Stroke mode, need to apply a smooth because
* the reprojection creates small jitter. */
if (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) {
float ifac = (float)brush->gpencil_settings->input_samples / 10.0f;
float sfac = interpf(1.0f, 0.2f, ifac);
- for (i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth_point(gps, i, sfac, false);
- BKE_gpencil_stroke_smooth_strength(gps, i, sfac);
+ for (i = 0; i < gps->totpoints; i++) {
+ BKE_gpencil_stroke_smooth_point(gps, i, sfac, 2, false, true, gps);
+ BKE_gpencil_stroke_smooth_strength(gps, i, sfac, 2, gps);
}
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 57a184b0e8d..01d433b9b2a 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1481,7 +1481,7 @@ static void gpencil_primitive_edit_event_handling(
break;
}
case MOUSEMOVE: {
- if ((event->val == KM_PRESS) && tgpi->sel_cp != SELECT_NONE) {
+ if (tgpi->sel_cp != SELECT_NONE) {
if (tgpi->sel_cp == SELECT_START && tgpi->tot_stored_edges == 0) {
copy_v2_v2(tgpi->start, tgpi->mval);
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 216971e514b..1e7159392e2 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -329,16 +329,16 @@ static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso,
/* perform smoothing */
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
- BKE_gpencil_stroke_smooth_point(gps, pt_index, inf, false);
+ BKE_gpencil_stroke_smooth_point(gps, pt_index, inf, 2, false, false, gps);
}
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) {
- BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf);
+ BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf, 2, gps);
}
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_THICKNESS) {
- BKE_gpencil_stroke_smooth_thickness(gps, pt_index, inf);
+ BKE_gpencil_stroke_smooth_thickness(gps, pt_index, inf, 2, gps);
}
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_UV) {
- BKE_gpencil_stroke_smooth_uv(gps, pt_index, inf);
+ BKE_gpencil_stroke_smooth_uv(gps, pt_index, inf, 2, gps);
}
return true;
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 fa53e7a76e4..2919001c5ce 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -21,19 +21,19 @@ struct Object;
struct Scene;
struct View3D;
-/* transform_snap_object.c */
+/* transform_snap_object.cc */
/* ED_transform_snap_object_*** API */
-typedef enum {
+typedef enum eSnapSelect {
SNAP_ALL = 0,
SNAP_NOT_SELECTED = 1,
SNAP_NOT_ACTIVE = 2,
- SNAP_ONLY_ACTIVE = 3,
+ SNAP_NOT_EDITED = 3,
SNAP_SELECTABLE = 4,
} eSnapSelect;
-typedef enum {
+typedef enum eSnapEditType {
SNAP_GEOM_FINAL = 0,
SNAP_GEOM_CAGE = 1,
SNAP_GEOM_EDIT = 2, /* Bmesh for mesh-type. */
@@ -59,13 +59,13 @@ struct SnapObjectHitDepth {
/** parameters that define which objects will be used to snap. */
struct SnapObjectParams {
/* Special context sensitive handling for the active or selected object. */
- char snap_select;
+ eSnapSelect snap_select;
/* Geometry for snapping in edit mode. */
- char edit_mode_type;
+ eSnapEditType edit_mode_type;
/* snap to the closest element, use when using more than one snap type */
- unsigned int use_occlusion_test : 1;
+ bool use_occlusion_test : true;
/* exclude back facing geometry from snapping */
- unsigned int use_backface_culling : 1;
+ bool use_backface_culling : true;
};
typedef struct SnapObjectContext SnapObjectContext;
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d2ff5637a13..53591e02f71 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -273,9 +273,8 @@ typedef enum {
V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE = 1 << 0,
V3D_SNAPCURSOR_OCCLUSION_ALWAYS_TRUE = 1 << 1,
V3D_SNAPCURSOR_OCCLUSION_ALWAYS_FALSE = 1 << 2, /* TODO. */
- V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE = 1 << 3,
- V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL = 1 << 4,
- V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE = 1 << 5,
+ V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL = 1 << 3,
+ V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE = 1 << 4,
} eV3DSnapCursor;
typedef enum {
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a223eac3000..74797f91046 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -157,6 +157,8 @@ enum {
UI_BLOCK_POPOVER_ONCE = 1 << 22,
/** Always show key-maps, even for non-menus. */
UI_BLOCK_SHOW_SHORTCUT_ALWAYS = 1 << 23,
+ /** Don't show library override state for buttons in this block. */
+ UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE = 1 << 24,
/** The block is only used during the search process and will not be drawn.
* Currently just for the case of a closed panel's sub-panel (and its sub-panels). */
UI_BLOCK_SEARCH_ONLY = 1 << 25,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 3619a7ce317..e83a8761e12 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -4238,28 +4238,28 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
int totitems = 0;
int categories = 0;
- int nbr_entries_nosepr = 0;
+ int entries_nosepr_count = 0;
for (const EnumPropertyItem *item = item_array; item->identifier; item++, totitems++) {
if (!item->identifier[0]) {
/* inconsistent, but menus with categories do not look good flipped */
if (item->name) {
block->flag |= UI_BLOCK_NO_FLIP;
categories++;
- nbr_entries_nosepr++;
+ entries_nosepr_count++;
}
- /* We do not want simple separators in nbr_entries_nosepr count */
+ /* We do not want simple separators in `entries_nosepr_count`. */
continue;
}
- nbr_entries_nosepr++;
+ entries_nosepr_count++;
}
/* Columns and row estimation. Ignore simple separators here. */
- int columns = (nbr_entries_nosepr + 20) / 20;
+ int columns = (entries_nosepr_count + 20) / 20;
if (columns < 1) {
columns = 1;
}
if (columns > 8) {
- columns = (nbr_entries_nosepr + 25) / 25;
+ columns = (entries_nosepr_count + 25) / 25;
}
int rows = totitems / columns;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index decd8c03d70..c02024bc82d 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -546,13 +546,13 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region),
#undef HISTOGRAM_TOT_GRID_LINES
-static void waveform_draw_one(float *waveform, int nbr, const float col[3])
+static void waveform_draw_one(float *waveform, int waveform_num, const float col[3])
{
GPUVertFormat format = {0};
const uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
- GPU_vertbuf_data_alloc(vbo, nbr);
+ GPU_vertbuf_data_alloc(vbo, waveform_num);
GPU_vertbuf_attr_fill(vbo, pos_id, waveform);
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 35cf952b5ce..b33cab3cbc6 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -4963,6 +4963,9 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
}
}
#endif
+ if (but->block->flag & UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE) {
+ state &= ~UI_BUT_OVERRIDDEN;
+ }
const float zoom = 1.0f / but->block->aspect;
wt->state(wt, state, drawflag, but->emboss);
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 98df418b5d4..51181f7caaa 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -201,6 +201,8 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
ot->poll = WM_operator_winactive;
ot->ui = wm_usd_export_draw;
+ ot->flag = OPTYPE_REGISTER; /* No UNDO possible. */
+
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER | FILE_TYPE_USD,
FILE_BLENDER,
@@ -459,6 +461,8 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
ot->poll = WM_operator_winactive;
ot->ui = wm_usd_import_draw;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
WM_operator_properties_filesel(ot,
FILE_TYPE_FOLDER | FILE_TYPE_USD,
FILE_BLENDER,
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index dbb6916dfce..d93edd2776b 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -515,7 +515,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;
- BKE_image_free_gputextures(ima);
+ BKE_image_partial_update_mark_full_update(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 3ca91c7e652..fec87fbfa95 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -180,7 +180,7 @@ static bool write_internal_bake_pixels(Image *image,
void *lock;
bool is_float;
char *mask_buffer = NULL;
- const size_t num_pixels = (size_t)width * (size_t)height;
+ const size_t pixels_num = (size_t)width * (size_t)height;
ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
@@ -189,8 +189,8 @@ static bool write_internal_bake_pixels(Image *image,
}
if (margin > 0 || !is_clear) {
- mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
- RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
}
is_float = (ibuf->rect_float != NULL);
@@ -298,7 +298,7 @@ static bool write_internal_bake_pixels(Image *image,
/* force OpenGL reload */
static void bake_targets_refresh(BakeTargets *targets)
{
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
Image *ima = targets->images[i].image;
if (ima) {
@@ -374,10 +374,10 @@ static bool write_external_bake_pixels(const char *filepath,
/* margins */
if (margin > 0) {
char *mask_buffer = NULL;
- const size_t num_pixels = (size_t)width * (size_t)height;
+ const size_t pixels_num = (size_t)width * (size_t)height;
- mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
- RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
+ mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask");
+ RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer);
RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer);
if (mask_buffer) {
@@ -670,9 +670,9 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr,
Object *ob,
ReportList *reports)
{
- int num_materials = ob->totcol;
+ int materials_num = ob->totcol;
- if (num_materials == 0) {
+ if (materials_num == 0) {
if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
BKE_report(
reports, RPT_ERROR, "No active image found, add a material or bake to an external file");
@@ -688,15 +688,15 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr,
}
/* Over-allocate in case there is more materials than images. */
- targets->num_materials = num_materials;
- targets->images = MEM_callocN(sizeof(BakeImage) * targets->num_materials, "BakeTargets.images");
- targets->material_to_image = MEM_callocN(sizeof(int) * targets->num_materials,
+ targets->materials_num = materials_num;
+ targets->images = MEM_callocN(sizeof(BakeImage) * targets->materials_num, "BakeTargets.images");
+ targets->material_to_image = MEM_callocN(sizeof(int) * targets->materials_num,
"BakeTargets.material_to_image");
/* Error handling and tag (in case multiple materials share the same image). */
BKE_main_id_tag_idcode(bkr->main, ID_IM, LIB_TAG_DOIT, false);
- for (int i = 0; i < num_materials; i++) {
+ for (int i = 0; i < materials_num; i++) {
Image *image;
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
@@ -713,10 +713,10 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr,
}
}
else {
- targets->material_to_image[i] = targets->num_images;
- targets->images[targets->num_images].image = image;
+ targets->material_to_image[i] = targets->images_num;
+ targets->images[targets->images_num].image = image;
image->id.tag |= LIB_TAG_DOIT;
- targets->num_images++;
+ targets->images_num++;
}
}
@@ -733,7 +733,7 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr,
}
/* Saving to image datablocks. */
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
BakeImage *bk_image = &targets->images[i];
void *lock;
ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock);
@@ -741,9 +741,9 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr,
if (ibuf) {
bk_image->width = ibuf->x;
bk_image->height = ibuf->y;
- bk_image->offset = targets->num_pixels;
+ bk_image->offset = targets->pixels_num;
- targets->num_pixels += (size_t)ibuf->x * (size_t)ibuf->y;
+ targets->pixels_num += (size_t)ibuf->x * (size_t)ibuf->y;
}
else {
BKE_image_release_ibuf(bk_image->image, ibuf, lock);
@@ -765,12 +765,12 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr,
{
bool all_ok = true;
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
BakeImage *bk_image = &targets->images[i];
const bool ok = write_internal_bake_pixels(bk_image->image,
pixel_array + bk_image->offset,
targets->result +
- bk_image->offset * targets->num_channels,
+ bk_image->offset * targets->channels_num,
bk_image->width,
bk_image->height,
bkr->margin,
@@ -809,15 +809,15 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr,
}
/* Saving to disk. */
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
BakeImage *bk_image = &targets->images[i];
bk_image->width = bkr->width;
bk_image->height = bkr->height;
- bk_image->offset = targets->num_pixels;
+ bk_image->offset = targets->pixels_num;
bk_image->image = NULL;
- targets->num_pixels += (size_t)bkr->width * (size_t)bkr->height;
+ targets->pixels_num += (size_t)bkr->width * (size_t)bkr->height;
if (!bkr->is_split_materials) {
break;
@@ -826,7 +826,7 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr,
if (!bkr->is_split_materials) {
/* saving a single image */
- for (int i = 0; i < targets->num_materials; i++) {
+ for (int i = 0; i < targets->materials_num; i++) {
targets->material_to_image[i] = 0;
}
}
@@ -844,7 +844,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
{
bool all_ok = true;
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
BakeImage *bk_image = &targets->images[i];
BakeData *bake = &bkr->scene->r.bake;
@@ -888,7 +888,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
const bool ok = write_external_bake_pixels(name,
pixel_array + bk_image->offset,
targets->result +
- bk_image->offset * targets->num_channels,
+ bk_image->offset * targets->channels_num,
bk_image->width,
bk_image->height,
bkr->margin,
@@ -934,11 +934,11 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
}
targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images");
- targets->num_images = 1;
+ targets->images_num = 1;
targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol,
"BakeTargets.material_to_image");
- targets->num_materials = ob->totcol;
+ targets->materials_num = ob->totcol;
BakeImage *bk_image = &targets->images[0];
bk_image->width = me->totloop;
@@ -946,7 +946,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
bk_image->offset = 0;
bk_image->image = NULL;
- targets->num_pixels = bk_image->width * bk_image->height;
+ targets->pixels_num = bk_image->width * bk_image->height;
return true;
}
@@ -984,10 +984,10 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
BakePixel *pixel_array)
{
Mesh *me = ob->data;
- const int num_pixels = targets->num_pixels;
+ const int pixels_num = targets->pixels_num;
/* Initialize blank pixels. */
- for (int i = 0; i < num_pixels; i++) {
+ for (int i = 0; i < pixels_num; i++) {
BakePixel *pixel = &pixel_array[i];
pixel->primitive_id = -1;
@@ -1059,12 +1059,12 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
MEM_freeN(looptri);
}
-static void bake_result_add_to_rgba(float rgba[4], const float *result, const int num_channels)
+static void bake_result_add_to_rgba(float rgba[4], const float *result, const int channels_num)
{
- if (num_channels == 4) {
+ if (channels_num == 4) {
add_v4_v4(rgba, result);
}
- else if (num_channels == 3) {
+ else if (channels_num == 3) {
add_v3_v3(rgba, result);
rgba[3] += 1.0f;
}
@@ -1082,7 +1082,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
const bool mcol_valid = (mcol != NULL);
MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
- const int num_channels = targets->num_channels;
+ const int channels_num = targets->channels_num;
const float *result = targets->result;
if (mcol_valid) {
@@ -1096,7 +1096,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
MLoop *mloop = me->mloop;
for (int i = 0; i < totloop; i++, mloop++) {
const int v = mloop->v;
- bake_result_add_to_rgba(mcol[v].color, &result[i * num_channels], num_channels);
+ bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num);
num_loops_for_vertex[v]++;
}
@@ -1118,7 +1118,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
for (int i = 0; i < totloop; i++, mloop++, mloopcol++) {
float rgba[4];
zero_v4(rgba);
- bake_result_add_to_rgba(rgba, &result[i * num_channels], num_channels);
+ bake_result_add_to_rgba(rgba, &result[i * channels_num], channels_num);
if (is_noncolor) {
unit_float_to_uchar_clamp_v4(&mloopcol->r, rgba);
@@ -1160,13 +1160,13 @@ static bool bake_targets_init(const BakeAPIRender *bkr,
}
}
- if (targets->num_pixels == 0) {
+ if (targets->pixels_num == 0) {
return false;
}
targets->is_noncolor = is_noncolor_pass(bkr->pass_type);
- targets->num_channels = RE_pass_depth(bkr->pass_type);
- targets->result = MEM_callocN(sizeof(float) * targets->num_channels * targets->num_pixels,
+ targets->channels_num = RE_pass_depth(bkr->pass_type);
+ targets->result = MEM_callocN(sizeof(float) * targets->channels_num * targets->pixels_num,
"bake return pixels");
return true;
@@ -1182,7 +1182,7 @@ static void bake_targets_populate_pixels(const BakeAPIRender *bkr,
bake_targets_populate_pixels_vertex_colors(targets, ob, me_eval, pixel_array);
}
else {
- RE_bake_pixels_populate(me_eval, pixel_array, targets->num_pixels, targets, bkr->uv_layer);
+ RE_bake_pixels_populate(me_eval, pixel_array, targets->pixels_num, targets, bkr->uv_layer);
}
}
@@ -1329,7 +1329,7 @@ static int bake(const BakeAPIRender *bkr,
/* Populate the pixel array with the face data. Except if we use a cage, then
* it is populated later with the cage mesh (smoothed version of the mesh). */
- pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels low poly");
+ pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels low poly");
if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) {
bake_targets_populate_pixels(bkr, &targets, ob_low, me_low_eval, pixel_array_low);
}
@@ -1422,7 +1422,7 @@ static int bake(const BakeAPIRender *bkr,
ob_low_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
/* populate the pixel arrays with the corresponding face data for each high poly object */
- pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels,
+ pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num,
"bake pixels high poly");
if (!RE_bake_pixels_populate_from_objects(me_low_eval,
@@ -1430,7 +1430,7 @@ static int bake(const BakeAPIRender *bkr,
pixel_array_high,
highpoly,
tot_highpoly,
- targets.num_pixels,
+ targets.pixels_num,
ob_cage != NULL,
bkr->cage_extrusion,
bkr->max_ray_distance,
@@ -1491,16 +1491,16 @@ static int bake(const BakeAPIRender *bkr,
break;
}
RE_bake_normal_world_to_world(pixel_array_low,
- targets.num_pixels,
- targets.num_channels,
+ targets.pixels_num,
+ targets.channels_num,
targets.result,
bkr->normal_swizzle);
break;
}
case R_BAKE_SPACE_OBJECT: {
RE_bake_normal_world_to_object(pixel_array_low,
- targets.num_pixels,
- targets.num_channels,
+ targets.pixels_num,
+ targets.channels_num,
targets.result,
ob_low_eval,
bkr->normal_swizzle);
@@ -1509,8 +1509,8 @@ static int bake(const BakeAPIRender *bkr,
case R_BAKE_SPACE_TANGENT: {
if (bkr->is_selected_to_active) {
RE_bake_normal_world_to_tangent(pixel_array_low,
- targets.num_pixels,
- targets.num_channels,
+ targets.pixels_num,
+ targets.channels_num,
targets.result,
me_low_eval,
bkr->normal_swizzle,
@@ -1535,8 +1535,8 @@ static int bake(const BakeAPIRender *bkr,
}
RE_bake_normal_world_to_tangent(pixel_array_low,
- targets.num_pixels,
- targets.num_channels,
+ targets.pixels_num,
+ targets.channels_num,
targets.result,
(me_nores) ? me_nores : me_low_eval,
bkr->normal_swizzle,
diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c
index 9b62823ea8a..d0a6a5d44c0 100644
--- a/source/blender/editors/object/object_gpencil_modifier.c
+++ b/source/blender/editors/object/object_gpencil_modifier.c
@@ -403,7 +403,7 @@ void OBJECT_OT_gpencil_modifier_add(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna,
"type",
- rna_enum_object_modifier_type_items,
+ rna_enum_object_greasepencil_modifier_type_items,
eGpencilModifierType_Thick,
"Type",
"");
diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c
index e8637b57724..b3f62f3fc0f 100644
--- a/source/blender/editors/object/object_hook.c
+++ b/source/blender/editors/object/object_hook.c
@@ -54,23 +54,26 @@
#include "object_intern.h"
-static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar, float r_cent[3])
+static int return_editmesh_indexar(BMEditMesh *em,
+ int *r_indexar_num,
+ int **r_indexar,
+ float r_cent[3])
{
BMVert *eve;
BMIter iter;
- int *index, nr, totvert = 0;
+ int *index, nr, indexar_num = 0;
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- totvert++;
+ indexar_num++;
}
}
- if (totvert == 0) {
+ if (indexar_num == 0) {
return 0;
}
- *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
- *r_tot = totvert;
+ *r_indexar = index = MEM_mallocN(4 * indexar_num, "hook indexar");
+ *r_indexar_num = indexar_num;
nr = 0;
zero_v3(r_cent);
@@ -83,9 +86,9 @@ static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar,
nr++;
}
- mul_v3_fl(r_cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)indexar_num);
- return totvert;
+ return indexar_num;
}
static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, float r_cent[3])
@@ -97,7 +100,7 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name,
if (cd_dvert_offset != -1) {
const int defgrp_index = active_index - 1;
- int totvert = 0;
+ int indexar_num = 0;
MDeformVert *dvert;
BMVert *eve;
@@ -109,14 +112,14 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name,
if (BKE_defvert_find_weight(dvert, defgrp_index) > 0.0f) {
add_v3_v3(r_cent, eve->co);
- totvert++;
+ indexar_num++;
}
}
- if (totvert) {
+ if (indexar_num) {
const ListBase *defbase = BKE_object_defgroup_list(obedit);
bDeformGroup *dg = BLI_findlink(defbase, defgrp_index);
BLI_strncpy(r_name, dg->name, sizeof(dg->name));
- mul_v3_fl(r_cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)indexar_num);
return true;
}
}
@@ -139,7 +142,7 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (nr == hmd->indexar[index]) {
BM_vert_select_set(em->bm, eve, true);
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
@@ -151,12 +154,12 @@ static void select_editbmesh_hook(Object *ob, HookModifierData *hmd)
}
static int return_editlattice_indexar(Lattice *editlatt,
- int *r_tot,
int **r_indexar,
+ int *r_indexar_num,
float r_cent[3])
{
BPoint *bp;
- int *index, nr, totvert = 0, a;
+ int *index, nr, indexar_num = 0, a;
/* count */
a = editlatt->pntsu * editlatt->pntsv * editlatt->pntsw;
@@ -164,18 +167,18 @@ static int return_editlattice_indexar(Lattice *editlatt,
while (a--) {
if (bp->f1 & SELECT) {
if (bp->hide == 0) {
- totvert++;
+ indexar_num++;
}
}
bp++;
}
- if (totvert == 0) {
+ if (indexar_num == 0) {
return 0;
}
- *r_indexar = index = MEM_mallocN(4 * totvert, "hook indexar");
- *r_tot = totvert;
+ *r_indexar = index = MEM_mallocN(4 * indexar_num, "hook indexar");
+ *r_indexar_num = indexar_num;
nr = 0;
zero_v3(r_cent);
@@ -193,9 +196,9 @@ static int return_editlattice_indexar(Lattice *editlatt,
nr++;
}
- mul_v3_fl(r_cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)indexar_num);
- return totvert;
+ return indexar_num;
}
static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
@@ -211,7 +214,7 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
while (a--) {
if (hmd->indexar[index] == nr) {
bp->f1 |= SELECT;
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
@@ -220,12 +223,15 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd)
}
}
-static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, float r_cent[3])
+static int return_editcurve_indexar(Object *obedit,
+ int **r_indexar,
+ int *r_indexar_num,
+ float r_cent[3])
{
ListBase *editnurb = object_editcurve_get(obedit);
BPoint *bp;
BezTriple *bezt;
- int *index, a, nr, totvert = 0;
+ int *index, a, nr, indexar_num = 0;
LISTBASE_FOREACH (Nurb *, nu, editnurb) {
if (nu->type == CU_BEZIER) {
@@ -233,13 +239,13 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar,
a = nu->pntsu;
while (a--) {
if (bezt->f1 & SELECT) {
- totvert++;
+ indexar_num++;
}
if (bezt->f2 & SELECT) {
- totvert++;
+ indexar_num++;
}
if (bezt->f3 & SELECT) {
- totvert++;
+ indexar_num++;
}
bezt++;
}
@@ -249,18 +255,18 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar,
a = nu->pntsu * nu->pntsv;
while (a--) {
if (bp->f1 & SELECT) {
- totvert++;
+ indexar_num++;
}
bp++;
}
}
}
- if (totvert == 0) {
+ if (indexar_num == 0) {
return 0;
}
- *r_indexar = index = MEM_mallocN(sizeof(*index) * totvert, "hook indexar");
- *r_tot = totvert;
+ *r_indexar = index = MEM_mallocN(sizeof(*index) * indexar_num, "hook indexar");
+ *r_indexar_num = indexar_num;
nr = 0;
zero_v3(r_cent);
@@ -305,21 +311,21 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar,
}
}
- mul_v3_fl(r_cent, 1.0f / (float)totvert);
+ mul_v3_fl(r_cent, 1.0f / (float)indexar_num);
- return totvert;
+ return indexar_num;
}
static bool object_hook_index_array(Main *bmain,
Scene *scene,
Object *obedit,
- int *r_tot,
int **r_indexar,
+ int *r_indexar_num,
char *r_name,
float r_cent[3])
{
*r_indexar = NULL;
- *r_tot = 0;
+ *r_indexar_num = 0;
r_name[0] = 0;
switch (obedit->type) {
@@ -338,7 +344,7 @@ static bool object_hook_index_array(Main *bmain,
BKE_editmesh_looptri_and_normals_calc(em);
/* check selected vertices first */
- if (return_editmesh_indexar(em, r_tot, r_indexar, r_cent) == 0) {
+ if (return_editmesh_indexar(em, r_indexar_num, r_indexar, r_cent) == 0) {
return return_editmesh_vgroup(obedit, em, r_name, r_cent);
}
return true;
@@ -347,10 +353,10 @@ static bool object_hook_index_array(Main *bmain,
case OB_SURF:
ED_curve_editnurb_load(bmain, obedit);
ED_curve_editnurb_make(obedit);
- return return_editcurve_indexar(obedit, r_tot, r_indexar, r_cent);
+ return return_editcurve_indexar(obedit, r_indexar, r_indexar_num, r_cent);
case OB_LATTICE: {
Lattice *lt = obedit->data;
- return return_editlattice_indexar(lt->editlatt->latt, r_tot, r_indexar, r_cent);
+ return return_editlattice_indexar(lt->editlatt->latt, r_indexar, r_indexar_num, r_cent);
}
default:
return false;
@@ -371,21 +377,21 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
while (a--) {
if (nr == hmd->indexar[index]) {
bezt->f1 |= SELECT;
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
nr++;
if (nr == hmd->indexar[index]) {
bezt->f2 |= SELECT;
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
nr++;
if (nr == hmd->indexar[index]) {
bezt->f3 |= SELECT;
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
@@ -400,7 +406,7 @@ static void select_editcurve_hook(Object *obedit, HookModifierData *hmd)
while (a--) {
if (nr == hmd->indexar[index]) {
bp->f1 |= SELECT;
- if (index < hmd->totindex - 1) {
+ if (index < hmd->indexar_num - 1) {
index++;
}
}
@@ -514,10 +520,10 @@ static int add_hook_object(const bContext *C,
HookModifierData *hmd = NULL;
float cent[3];
float pose_mat[4][4];
- int tot, ok, *indexar;
+ int indexar_num, ok, *indexar;
char name[MAX_NAME];
- ok = object_hook_index_array(bmain, scene, obedit, &tot, &indexar, name, cent);
+ ok = object_hook_index_array(bmain, scene, obedit, &indexar, &indexar_num, name, cent);
if (!ok) {
BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group");
@@ -545,7 +551,7 @@ static int add_hook_object(const bContext *C,
hmd->object = ob;
hmd->indexar = indexar;
copy_v3_v3(hmd->cent, cent);
- hmd->totindex = tot;
+ hmd->indexar_num = indexar_num;
BLI_strncpy(hmd->name, name, sizeof(hmd->name));
unit_m4(pose_mat);
@@ -873,7 +879,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op)
HookModifierData *hmd = NULL;
float cent[3];
char name[MAX_NAME];
- int *indexar, tot;
+ int *indexar, indexar_num;
object_hook_from_context(C, &ptr, num, &ob, &hmd);
if (hmd == NULL) {
@@ -883,7 +889,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op)
/* assign functionality */
- if (!object_hook_index_array(bmain, scene, ob, &tot, &indexar, name, cent)) {
+ if (!object_hook_index_array(bmain, scene, ob, &indexar, &indexar_num, name, cent)) {
BKE_report(op->reports, RPT_WARNING, "Requires selected vertices or active vertex group");
return OPERATOR_CANCELLED;
}
@@ -893,7 +899,7 @@ static int object_hook_assign_exec(bContext *C, wmOperator *op)
copy_v3_v3(hmd->cent, cent);
hmd->indexar = indexar;
- hmd->totindex = tot;
+ hmd->indexar_num = indexar_num;
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 7fedc2c6265..7c3571d3b75 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -541,36 +541,36 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports),
return false;
}
- int totpart = psys_eval->totcached;
- int totchild = psys_eval->totchildcache;
+ int part_num = psys_eval->totcached;
+ int child_num = psys_eval->totchildcache;
- if (totchild && (part->draw & PART_DRAW_PARENT) == 0) {
- totpart = 0;
+ if (child_num && (part->draw & PART_DRAW_PARENT) == 0) {
+ part_num = 0;
}
/* count */
- int totvert = 0, totedge = 0;
+ int verts_num = 0, edges_num = 0;
ParticleCacheKey **cache = psys_eval->pathcache;
- for (int a = 0; a < totpart; a++) {
+ for (int a = 0; a < part_num; a++) {
ParticleCacheKey *key = cache[a];
if (key->segments > 0) {
- totvert += key->segments + 1;
- totedge += key->segments;
+ verts_num += key->segments + 1;
+ edges_num += key->segments;
}
}
cache = psys_eval->childcache;
- for (int a = 0; a < totchild; a++) {
+ for (int a = 0; a < child_num; a++) {
ParticleCacheKey *key = cache[a];
if (key->segments > 0) {
- totvert += key->segments + 1;
- totedge += key->segments;
+ verts_num += key->segments + 1;
+ edges_num += key->segments;
}
}
- if (totvert == 0) {
+ if (verts_num == 0) {
return false;
}
@@ -578,11 +578,11 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports),
Object *obn = BKE_object_add(bmain, view_layer, OB_MESH, NULL);
Mesh *me = obn->data;
- me->totvert = totvert;
- me->totedge = totedge;
+ me->totvert = verts_num;
+ me->totedge = edges_num;
- me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
- me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+ me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, verts_num);
+ me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, edges_num);
me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
MVert *mvert = me->mvert;
@@ -590,7 +590,7 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports),
/* copy coordinates */
cache = psys_eval->pathcache;
- for (int a = 0; a < totpart; a++) {
+ for (int a = 0; a < part_num; a++) {
ParticleCacheKey *key = cache[a];
int kmax = key->segments;
for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
@@ -609,7 +609,7 @@ bool ED_object_modifier_convert(ReportList *UNUSED(reports),
}
cache = psys_eval->childcache;
- for (int a = 0; a < totchild; a++) {
+ for (int a = 0; a < child_num; a++) {
ParticleCacheKey *key = cache[a];
int kmax = key->segments;
for (int k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
@@ -774,9 +774,9 @@ static bool modifier_apply_obdata(
RPT_INFO,
"Applied modifier only changed CV points, not tessellated/bevel vertices");
- int numVerts;
- float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &numVerts);
- mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts);
+ int verts_num;
+ float(*vertexCos)[3] = BKE_curve_nurbs_vert_coords_alloc(&curve_eval->nurb, &verts_num);
+ mti->deformVerts(md_eval, &mectx, NULL, vertexCos, verts_num);
BKE_curve_nurbs_vert_coords_apply(&curve->nurb, vertexCos, false);
MEM_freeN(vertexCos);
@@ -793,9 +793,9 @@ static bool modifier_apply_obdata(
return false;
}
- int numVerts;
- float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &numVerts);
- mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts);
+ int verts_num;
+ float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &verts_num);
+ mti->deformVerts(md_eval, &mectx, NULL, vertexCos, verts_num);
BKE_lattice_vert_coords_apply(lattice, vertexCos);
MEM_freeN(vertexCos);
@@ -2781,9 +2781,9 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
MEM_SAFE_FREE(mmd->dynverts);
MEM_SAFE_FREE(mmd->bindweights); /* Deprecated */
MEM_SAFE_FREE(mmd->bindcos); /* Deprecated */
- mmd->totvert = 0;
- mmd->totcagevert = 0;
- mmd->totinfluence = 0;
+ mmd->verts_num = 0;
+ mmd->cage_verts_num = 0;
+ mmd->influences_num = 0;
}
else {
/* Force modifier to run, it will call binding routine
@@ -3119,7 +3119,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op)
/* This is hard to know from the modifier itself whether the evaluation is
* happening for binding or not. So we copy all the required data here. */
- lmd->total_verts = lmd_eval->total_verts;
+ lmd->verts_num = lmd_eval->verts_num;
if (lmd_eval->vertexco == NULL) {
MEM_SAFE_FREE(lmd->vertexco);
}
diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc
index 24425b5a991..afd2c048379 100644
--- a/source/blender/editors/object/object_transform.cc
+++ b/source/blender/editors/object/object_transform.cc
@@ -1695,13 +1695,13 @@ static void object_apply_rotation(Object *ob, const float rmat[3][3])
static void object_apply_location(Object *ob, const float loc[3])
{
/* quick but weak */
- Object ob_prev = *ob;
+ Object ob_prev = blender::dna::shallow_copy(*ob);
float mat[4][4];
copy_m4_m4(mat, ob->obmat);
copy_v3_v3(mat[3], loc);
BKE_object_apply_mat4(ob, mat, true, true);
copy_v3_v3(mat[3], ob->loc);
- *ob = ob_prev;
+ *ob = blender::dna::shallow_copy(ob_prev);
copy_v3_v3(ob->loc, mat[3]);
}
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 5bc062eb177..e8ceb97ed7a 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -399,27 +399,27 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
* Save output images
*/
{
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
/* primary output layer */
if (surface->flags & MOD_DPAINT_OUT1) {
/* set filepath */
BLI_join_dirfile(
- filename, sizeof(filename), surface->image_output_path, surface->output_name);
- BLI_path_frame(filename, frame, 4);
+ filepath, sizeof(filepath), surface->image_output_path, surface->output_name);
+ BLI_path_frame(filepath, frame, 4);
/* save image */
- dynamicPaint_outputSurfaceImage(surface, filename, 0);
+ dynamicPaint_outputSurfaceImage(surface, filepath, 0);
}
/* secondary output */
if (surface->flags & MOD_DPAINT_OUT2 && surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
/* set filepath */
BLI_join_dirfile(
- filename, sizeof(filename), surface->image_output_path, surface->output_name2);
- BLI_path_frame(filename, frame, 4);
+ filepath, sizeof(filepath), surface->image_output_path, surface->output_name2);
+ BLI_path_frame(filepath, frame, 4);
/* save image */
- dynamicPaint_outputSurfaceImage(surface, filename, 1);
+ dynamicPaint_outputSurfaceImage(surface, filepath, 1);
}
}
}
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index fa90d1e64d6..a77d70d5d9b 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -192,7 +192,7 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot)
FILE_TYPE_FOLDER,
FILE_SPECIAL,
FILE_SAVE,
- FILE_RELPATH,
+ WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY,
FILE_SORT_DEFAULT);
}
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index 16a3e799779..ef0f0b6225c 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -1679,19 +1679,19 @@ class PreviewLoadJob {
PreviewLoadJob();
~PreviewLoadJob();
- static PreviewLoadJob &ensure_job(wmWindowManager *, wmWindow *);
- static void load_jobless(PreviewImage *, eIconSizes);
+ static PreviewLoadJob &ensure_job(wmWindowManager *wm, wmWindow *win);
+ static void load_jobless(PreviewImage *preview, eIconSizes icon_size);
- void push_load_request(PreviewImage *, eIconSizes);
+ void push_load_request(PreviewImage *preview, eIconSizes icon_size);
private:
- static void run_fn(void *, short *, short *, float *);
- static void update_fn(void *);
- static void end_fn(void *);
- static void free_fn(void *);
+ static void run_fn(void *customdata, short *stop, short *do_update, float *progress);
+ static void update_fn(void *customdata);
+ static void end_fn(void *customdata);
+ static void free_fn(void *customdata);
/** Mark a single requested preview as being done, remove the request. */
- static void finish_request(RequestedPreview &);
+ static void finish_request(RequestedPreview &request);
};
PreviewLoadJob::PreviewLoadJob() : todo_queue_(BLI_thread_queue_init())
diff --git a/source/blender/editors/scene/CMakeLists.txt b/source/blender/editors/scene/CMakeLists.txt
index 7f687212066..12043ac2957 100644
--- a/source/blender/editors/scene/CMakeLists.txt
+++ b/source/blender/editors/scene/CMakeLists.txt
@@ -8,8 +8,8 @@ set(INC
../../depsgraph
../../makesdna
../../makesrna
- ../../windowmanager
../../sequencer
+ ../../windowmanager
)
set(INC_SYS
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index af84f6f99a9..30bf23e0987 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1972,6 +1972,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
static void area_offscreen_init(ScrArea *area)
{
+ area->flag |= AREA_FLAG_OFFSCREEN;
area->type = BKE_spacetype_from_id(area->spacetype);
if (area->type == NULL) {
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 7392f05aea4..d0ff1d09c39 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -13,8 +13,8 @@ set(INC
../../gpu
../../imbuf
../../makesdna
- ../../nodes
../../makesrna
+ ../../nodes
../../render
../../windowmanager
../../../../intern/atomic
@@ -38,9 +38,9 @@ set(SRC
paint_curve_undo.c
paint_hide.c
paint_image.cc
- paint_image_ops_paint.cc
paint_image_2d.c
paint_image_2d_curve_mask.cc
+ paint_image_ops_paint.cc
paint_image_proj.c
paint_mask.c
paint_ops.c
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc
index 94c0f5536b7..945bb09c0c6 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_3d_brush.cc
@@ -65,7 +65,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
/* New candidate is in inner radius while old one is not. */
return true;
}
- else if (b.depth_sq_cu < a.depth_sq_cu) {
+ if (b.depth_sq_cu < a.depth_sq_cu) {
/* Both candidates are in inner radius, but new one is closer to the camera. */
return true;
}
@@ -93,7 +93,7 @@ static std::optional<float3> find_curves_brush_position(const CurvesGeometry &cu
BrushPositionCandidate best_candidate = init;
for (const int curve_i : curves_range) {
- const IndexRange points = curves.range_for_curve(curve_i);
+ const IndexRange points = curves.points_for_curve(curve_i);
const int tot_segments = points.size() - 1;
for (const int segment_i : IndexRange(tot_segments)) {
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
index e57a6e43983..809511d0106 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
@@ -55,7 +55,7 @@ class AddOperation : public CurvesSculptStrokeOperation {
friend struct AddOperationExecutor;
public:
- ~AddOperation()
+ ~AddOperation() override
{
if (curve_roots_kdtree_ != nullptr) {
BLI_kdtree_3d_free(curve_roots_kdtree_);
@@ -174,8 +174,8 @@ struct AddOperationExecutor {
use_interpolation_ = interpolate_length_ || interpolate_shape_;
new_curve_length_ = curves_sculpt_->curve_length;
- tot_old_curves_ = curves_->curves_size();
- tot_old_points_ = curves_->points_size();
+ tot_old_curves_ = curves_->curves_num();
+ tot_old_points_ = curves_->points_num();
if (add_amount_ == 0) {
return;
@@ -216,8 +216,8 @@ struct AddOperationExecutor {
const int tot_added_curves = added_points.bary_coords.size();
const int tot_added_points = tot_added_curves * points_per_curve_;
- curves_->resize(curves_->points_size() + tot_added_points,
- curves_->curves_size() + tot_added_curves);
+ curves_->resize(curves_->points_num() + tot_added_points,
+ curves_->curves_num() + tot_added_curves);
threading::parallel_invoke([&]() { this->initialize_curve_offsets(tot_added_curves); },
[&]() { this->initialize_attributes(added_points); });
@@ -515,7 +515,7 @@ struct AddOperationExecutor {
void ensure_curve_roots_kdtree()
{
if (self_->curve_roots_kdtree_ == nullptr) {
- self_->curve_roots_kdtree_ = BLI_kdtree_3d_new(curves_->curves_size());
+ self_->curve_roots_kdtree_ = BLI_kdtree_3d_new(curves_->curves_num());
for (const int curve_i : curves_->curves_range()) {
const int root_point_i = curves_->offsets()[curve_i];
const float3 &root_pos_cu = curves_->positions()[root_point_i];
@@ -609,7 +609,7 @@ struct AddOperationExecutor {
const Span<NeighborInfo> neighbors = neighbors_per_curve[added_curve_i];
float length_sum = 0.0f;
for (const NeighborInfo &neighbor : neighbors) {
- const IndexRange neighbor_points = curves_->range_for_curve(neighbor.index);
+ const IndexRange neighbor_points = curves_->points_for_curve(neighbor.index);
float neighbor_length = 0.0f;
const int tot_segments = neighbor_points.size() - 1;
for (const int segment_i : IndexRange(tot_segments)) {
@@ -744,7 +744,7 @@ struct AddOperationExecutor {
float normal_rotation_cu[3][3];
rotation_between_vecs_to_mat3(normal_rotation_cu, neighbor_normal_cu, normal_cu);
- const IndexRange neighbor_points = curves_->range_for_curve(neighbor_curve_i);
+ const IndexRange neighbor_points = curves_->points_for_curve(neighbor_curve_i);
const float3 &neighbor_root_cu = positions_cu[neighbor_points[0]];
/* Use a temporary #PolySpline, because that's the easiest way to resample an
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
index 35b2b2ce956..d062fe32cfe 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc
@@ -202,7 +202,7 @@ struct CombOperationExecutor {
Vector<int> &local_changed_curves = r_changed_curves.local();
for (const int curve_i : curves_range) {
bool curve_changed = false;
- const IndexRange points = curves_->range_for_curve(curve_i);
+ const IndexRange points = curves_->points_for_curve(curve_i);
for (const int point_i : points.drop_front(1)) {
const float3 old_pos_cu = positions_cu[point_i];
@@ -274,7 +274,7 @@ struct CombOperationExecutor {
Vector<int> &local_changed_curves = r_changed_curves.local();
for (const int curve_i : curves_range) {
bool curve_changed = false;
- const IndexRange points = curves_->range_for_curve(curve_i);
+ const IndexRange points = curves_->points_for_curve(curve_i);
for (const int point_i : points.drop_front(1)) {
const float3 pos_old_cu = positions_cu[point_i];
@@ -324,10 +324,10 @@ struct CombOperationExecutor {
void initialize_segment_lengths()
{
const Span<float3> positions_cu = curves_->positions();
- self_->segment_lengths_cu_.reinitialize(curves_->points_size());
+ self_->segment_lengths_cu_.reinitialize(curves_->points_num());
threading::parallel_for(curves_->curves_range(), 128, [&](const IndexRange range) {
for (const int curve_i : range) {
- const IndexRange points = curves_->range_for_curve(curve_i);
+ const IndexRange points = curves_->points_for_curve(curve_i);
for (const int point_i : points.drop_back(1)) {
const float3 &p1_cu = positions_cu[point_i];
const float3 &p2_cu = positions_cu[point_i + 1];
@@ -349,7 +349,7 @@ struct CombOperationExecutor {
threading::parallel_for_each(changed_curves, [&](const Vector<int> &changed_curves) {
threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) {
for (const int curve_i : changed_curves.as_span().slice(range)) {
- const IndexRange points = curves_->range_for_curve(curve_i);
+ const IndexRange points = curves_->points_for_curve(curve_i);
for (const int segment_i : IndexRange(points.size() - 1)) {
const float3 &p1_cu = positions_cu[points[segment_i]];
float3 &p2_cu = positions_cu[points[segment_i] + 1];
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
index efe85dc132a..ae87f414dd5 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc
@@ -70,7 +70,7 @@ class DeleteOperation : public CurvesSculptStrokeOperation {
Vector<int64_t> indices;
const IndexMask curves_to_remove = index_mask_ops::find_indices_based_on_predicate(
curves.curves_range(), 512, indices, [&](const int curve_i) {
- const IndexRange point_range = curves.range_for_curve(curve_i);
+ const IndexRange point_range = curves.points_for_curve(curve_i);
for (const int segment_i : IndexRange(point_range.size() - 1)) {
const float3 pos1 = positions[point_range[segment_i]];
const float3 pos2 = positions[point_range[segment_i + 1]];
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
index b9a019a012c..382f0529daa 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
@@ -117,7 +117,7 @@ class ShrinkOperation : public CurvesSculptStrokeOperation {
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
- const IndexRange curve_points = curves.range_for_curve(curve_i);
+ const IndexRange curve_points = curves.points_for_curve(curve_i);
const int last_point_i = curve_points.last();
const float3 old_tip_position = positions[last_point_i];
@@ -304,7 +304,7 @@ class DensityAddOperation : public CurvesSculptStrokeOperation {
if (old_kdtree_ == nullptr && minimum_distance > 0.0f) {
old_kdtree_ = this->kdtree_from_curve_roots_and_positions(curves, curves.curves_range(), {});
- old_kdtree_size_ = curves.curves_size();
+ old_kdtree_size_ = curves.curves_num();
}
float density;
@@ -525,7 +525,7 @@ class DensityAddOperation : public CurvesSculptStrokeOperation {
{
Array<bool> elimination_mask(points.positions.size(), false);
- const int curves_added_previously = curves.curves_size() - old_kdtree_size_;
+ const int curves_added_previously = curves.curves_num() - old_kdtree_size_;
KDTree_3d *new_points_kdtree = this->kdtree_from_curve_roots_and_positions(
curves, IndexRange(old_kdtree_size_, curves_added_previously), points.positions);
@@ -589,14 +589,14 @@ class DensityAddOperation : public CurvesSculptStrokeOperation {
const int tot_new_curves = new_points.positions.size();
const int points_per_curve = 8;
- curves.resize(curves.points_size() + tot_new_curves * points_per_curve,
- curves.curves_size() + tot_new_curves);
+ curves.resize(curves.points_num() + tot_new_curves * points_per_curve,
+ curves.curves_num() + tot_new_curves);
MutableSpan<int> offsets = curves.offsets();
MutableSpan<float3> positions = curves.positions();
for (const int i : IndexRange(tot_new_curves)) {
- const int curve_i = curves.curves_size() - tot_new_curves + i;
+ const int curve_i = curves.curves_num() - tot_new_curves + i;
const int first_point_i = offsets[curve_i];
offsets[curve_i + 1] = offsets[curve_i] + points_per_curve;
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
index bd6b238ea72..682cd3b47ca 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc
@@ -83,7 +83,7 @@ class SnakeHookOperation : public CurvesSculptStrokeOperation {
threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) {
for (const int curve_i : curves_range) {
- const IndexRange curve_points = curves.range_for_curve(curve_i);
+ const IndexRange curve_points = curves.points_for_curve(curve_i);
const int last_point_i = curve_points.last();
const float3 old_position = positions[last_point_i];
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 2b55eb379cc..36dac998303 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -1076,7 +1076,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points);
trim_operation->mesh = BKE_mesh_new_nomain(
trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys);
- trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco");
+ trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco");
float depth_front = trim_operation->depth_front;
float depth_back = trim_operation->depth_back;
@@ -1130,7 +1130,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
/* Get the triangulation for the front/back poly. */
const int tot_tris_face = tot_screen_points - 2;
- uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris");
+ uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris");
BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris);
/* Write the front face triangle indices. */
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 70f8f2127b4..8bf09ce3d05 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -532,9 +532,8 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
{
const int totvert = SCULPT_vertex_count_get(ss);
boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN(
- totvert, 3 * sizeof(float), "pivot rotation axis");
- boundary->bend.pivot_positions = MEM_calloc_arrayN(
- totvert, 3 * sizeof(float), "pivot positions");
+ totvert, sizeof(float[3]), "pivot rotation axis");
+ boundary->bend.pivot_positions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "pivot positions");
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
@@ -567,7 +566,7 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo
static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary)
{
const int totvert = SCULPT_vertex_count_get(ss);
- boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
+ boundary->slide.directions = MEM_calloc_arrayN(totvert, sizeof(float[3]), "slide directions");
for (int i = 0; i < totvert; i++) {
if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) {
@@ -592,7 +591,7 @@ static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *b
{
zero_v3(boundary->twist.pivot_position);
float(*poly_verts)[3] = MEM_malloc_arrayN(
- boundary->num_vertices, sizeof(float) * 3, "poly verts");
+ boundary->num_vertices, sizeof(float[3]), "poly verts");
for (int i = 0; i < boundary->num_vertices; i++) {
add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i]));
copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i]));
diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c
index d12ae75464f..53babc3d36d 100644
--- a/source/blender/editors/sculpt_paint/sculpt_smooth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c
@@ -255,7 +255,7 @@ static void SCULPT_enhance_details_brush(Sculpt *sd,
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
const int totvert = SCULPT_vertex_count_get(ss);
ss->cache->detail_directions = MEM_malloc_arrayN(
- totvert, 3 * sizeof(float), "details directions");
+ totvert, sizeof(float[3]), "details directions");
for (int i = 0; i < totvert; i++) {
float avg[3];
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index f0ada312d82..d33cf70e117 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -1706,8 +1706,8 @@ static const EnumPropertyItem prop_actkeys_snap_types[] = {
"NEAREST_FRAME",
0,
"Selection to Nearest Frame",
- "Snap selected keyframes to the nearest (whole) frame (use to fix accidental subframe "
- "offsets)"},
+ "Snap selected keyframes to the nearest (whole) frame "
+ "(use to fix accidental sub-frame offsets)"},
{ACTKEYS_SNAP_NEAREST_SECOND,
"NEAREST_SECOND",
0,
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index f91ed5eb4f3..10fb008049d 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -207,13 +207,13 @@ static int file_browse_exec(bContext *C, wmOperator *op)
/* Do this first so '//' isn't converted to '//\' on windows. */
BLI_path_slash_ensure(path);
if (is_relative) {
- const int path_len = BLI_strncpy_rlen(path, str, FILE_MAX);
BLI_path_rel(path, BKE_main_blendfile_path(bmain));
- str = MEM_reallocN(str, path_len + 2);
- BLI_strncpy(str, path, FILE_MAX);
+ str_len = strlen(path);
+ str = MEM_reallocN(str, str_len + 1);
+ memcpy(str, path, str_len + 1);
}
else {
- str = MEM_reallocN(str, str_len + 2);
+ str = MEM_reallocN(str, str_len + 1);
}
}
else {
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 6660ff3b78b..e7bdbfe7c68 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -876,24 +876,24 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
BKE_tracking_marker_clamp(data->marker, CLAMP_PAT_DIM);
}
else if (data->action == SLIDE_ACTION_TILT_SIZE) {
- float start[2], end[2];
- float scale = 1.0f, angle = 0.0f;
- float mval[2];
-
- if (data->accurate) {
- mval[0] = data->mval[0] + (event->mval[0] - data->mval[0]) / 5.0f;
- mval[1] = data->mval[1] + (event->mval[1] - data->mval[1]) / 5.0f;
- }
- else {
- mval[0] = event->mval[0];
- mval[1] = event->mval[1];
- }
+ const float mouse_delta[2] = {dx, dy};
+ /* Vector which connects marker position with tilt/scale sliding area before sliding
+ * began. */
+ float start[2];
sub_v2_v2v2(start, data->spos, data->old_pos);
+ start[0] *= data->width;
+ start[1] *= data->height;
- ED_clip_point_stable_pos(sc, region, mval[0], mval[1], &end[0], &end[1]);
+ /* Vector which connects marker position with tilt/scale sliding area with the sliding
+ * delta applied. */
+ float end[2];
+ add_v2_v2v2(end, data->spos, mouse_delta);
sub_v2_v2(end, data->old_pos);
+ end[0] *= data->width;
+ end[1] *= data->height;
+ float scale = 1.0f;
if (len_squared_v2(start) != 0.0f) {
scale = len_v2(end) / len_v2(start);
@@ -902,7 +902,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
}
- angle = -angle_signed_v2v2(start, end);
+ const float angle = -angle_signed_v2v2(start, end);
for (int a = 0; a < 4; a++) {
float vec[2];
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index c4c6fa01025..b8c28e354da 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -79,6 +79,9 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 180e30a11d4..ceac53bde6b 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -1056,10 +1056,10 @@ void filelist_tag_needs_filtering(FileList *filelist)
void filelist_filter(FileList *filelist)
{
int num_filtered = 0;
- const int num_files = filelist->filelist.nbr_entries;
+ const int num_files = filelist->filelist.entries_num;
FileListInternEntry **filtered_tmp, *file;
- if (ELEM(filelist->filelist.nbr_entries, FILEDIR_NBR_ENTRIES_UNSET, 0)) {
+ if (ELEM(filelist->filelist.entries_num, FILEDIR_NBR_ENTRIES_UNSET, 0)) {
return;
}
@@ -1099,8 +1099,8 @@ void filelist_filter(FileList *filelist)
memcpy(filelist->filelist_intern.filtered,
filtered_tmp,
sizeof(*filelist->filelist_intern.filtered) * (size_t)num_filtered);
- filelist->filelist.nbr_entries_filtered = num_filtered;
- // printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.nbr_entries);
+ filelist->filelist.entries_filtered_num = num_filtered;
+ // printf("Filetered: %d over %d entries\n", num_filtered, filelist->filelist.entries_num);
filelist_cache_clear(&filelist->filelist_cache, filelist->filelist_cache.size);
filelist->flags &= ~FL_NEED_FILTERING;
@@ -1552,8 +1552,8 @@ static void filelist_direntryarr_free(FileDirEntryArr *array)
#else
BLI_assert(BLI_listbase_is_empty(&array->entries));
#endif
- array->nbr_entries = FILEDIR_NBR_ENTRIES_UNSET;
- array->nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET;
+ array->entries_num = FILEDIR_NBR_ENTRIES_UNSET;
+ array->entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET;
}
static void filelist_intern_entry_free(FileListInternEntry *entry)
@@ -1874,7 +1874,7 @@ FileList *filelist_new(short type)
filelist_cache_init(&p->filelist_cache, FILELIST_ENTRYCACHESIZE_DEFAULT);
p->selection_state = BLI_ghash_new(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, __func__);
- p->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET;
+ p->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET;
filelist_settype(p, type);
return p;
@@ -1979,9 +1979,9 @@ static void filelist_clear_main_files(FileList *filelist,
const int removed_files = filelist_intern_free_main_files(&filelist->filelist_intern);
- filelist->filelist.nbr_entries -= removed_files;
- filelist->filelist.nbr_entries_filtered = FILEDIR_NBR_ENTRIES_UNSET;
- BLI_assert(filelist->filelist.nbr_entries > FILEDIR_NBR_ENTRIES_UNSET);
+ filelist->filelist.entries_num -= removed_files;
+ filelist->filelist.entries_filtered_num = FILEDIR_NBR_ENTRIES_UNSET;
+ BLI_assert(filelist->filelist.entries_num > FILEDIR_NBR_ENTRIES_UNSET);
if (do_selection && filelist->selection_state) {
BLI_ghash_clear(filelist->selection_state, NULL, NULL);
@@ -2167,7 +2167,7 @@ int filelist_files_ensure(FileList *filelist)
filelist_filter(filelist);
}
- return filelist->filelist.nbr_entries_filtered;
+ return filelist->filelist.entries_filtered_num;
}
static FileDirEntry *filelist_file_create_entry(FileList *filelist, const int index)
@@ -2226,7 +2226,7 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const
const size_t cache_size = cache->size;
int old_index;
- if ((index < 0) || (index >= filelist->filelist.nbr_entries_filtered)) {
+ if ((index < 0) || (index >= filelist->filelist.entries_filtered_num)) {
return ret;
}
@@ -2274,7 +2274,7 @@ FileDirEntry *filelist_file(struct FileList *filelist, int index)
int filelist_file_find_path(struct FileList *filelist, const char *filename)
{
- if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) {
+ if (filelist->filelist.entries_filtered_num == FILEDIR_NBR_ENTRIES_UNSET) {
return -1;
}
@@ -2282,7 +2282,7 @@ int filelist_file_find_path(struct FileList *filelist, const char *filename)
* This is only used to find again renamed entry,
* annoying but looks hairy to get rid of it currently. */
- for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
+ for (int fidx = 0; fidx < filelist->filelist.entries_filtered_num; fidx++) {
FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx];
if (STREQ(entry->relpath, filename)) {
return fidx;
@@ -2294,11 +2294,11 @@ int filelist_file_find_path(struct FileList *filelist, const char *filename)
int filelist_file_find_id(const FileList *filelist, const ID *id)
{
- if (filelist->filelist.nbr_entries_filtered == FILEDIR_NBR_ENTRIES_UNSET) {
+ if (filelist->filelist.entries_filtered_num == FILEDIR_NBR_ENTRIES_UNSET) {
return -1;
}
- for (int fidx = 0; fidx < filelist->filelist.nbr_entries_filtered; fidx++) {
+ for (int fidx = 0; fidx < filelist->filelist.entries_filtered_num; fidx++) {
FileListInternEntry *entry = filelist->filelist_intern.filtered[fidx];
if (entry->local_data.id == id) {
return fidx;
@@ -2408,23 +2408,23 @@ bool filelist_file_cache_block(struct FileList *filelist, const int index)
FileListEntryCache *cache = &filelist->filelist_cache;
const size_t cache_size = cache->size;
- const int nbr_entries = filelist->filelist.nbr_entries_filtered;
+ const int entries_num = filelist->filelist.entries_filtered_num;
int start_index = max_ii(0, index - (cache_size / 2));
- int end_index = min_ii(nbr_entries, index + (cache_size / 2));
+ int end_index = min_ii(entries_num, index + (cache_size / 2));
int i;
const bool full_refresh = (filelist->flags & FL_IS_READY) == 0;
- if ((index < 0) || (index >= nbr_entries)) {
- // printf("Wrong index %d ([%d:%d])", index, 0, nbr_entries);
+ if ((index < 0) || (index >= entries_num)) {
+ // printf("Wrong index %d ([%d:%d])", index, 0, entries_num);
return false;
}
/* Maximize cached range! */
if ((end_index - start_index) < cache_size) {
if (start_index == 0) {
- end_index = min_ii(nbr_entries, start_index + cache_size);
+ end_index = min_ii(entries_num, start_index + cache_size);
}
- else if (end_index == nbr_entries) {
+ else if (end_index == entries_num) {
start_index = max_ii(0, end_index - cache_size);
}
}
@@ -2861,7 +2861,7 @@ int ED_file_extension_icon(const char *path)
int filelist_needs_reading(FileList *filelist)
{
- return (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET) ||
+ return (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET) ||
filelist_needs_force_reset(filelist);
}
@@ -2926,8 +2926,8 @@ void filelist_entries_select_index_range_set(
FileList *filelist, FileSelection *sel, FileSelType select, uint flag, FileCheckType check)
{
/* select all valid files between first and last indicated */
- if ((sel->first >= 0) && (sel->first < filelist->filelist.nbr_entries_filtered) &&
- (sel->last >= 0) && (sel->last < filelist->filelist.nbr_entries_filtered)) {
+ if ((sel->first >= 0) && (sel->first < filelist->filelist.entries_filtered_num) &&
+ (sel->last >= 0) && (sel->last < filelist->filelist.entries_filtered_num)) {
int current_file;
for (current_file = sel->first; current_file <= sel->last; current_file++) {
filelist_entry_select_index_set(filelist, current_file, select, flag, check);
@@ -2963,7 +2963,7 @@ uint filelist_entry_select_index_get(FileList *filelist, const int index, FileCh
bool filelist_entry_is_selected(FileList *filelist, const int index)
{
- BLI_assert(index >= 0 && index < filelist->filelist.nbr_entries_filtered);
+ BLI_assert(index >= 0 && index < filelist->filelist.entries_filtered_num);
FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index];
/* BLI_ghash_lookup returns NULL if not found, which gets mapped to 0, which gets mapped to
@@ -3030,13 +3030,13 @@ static int filelist_readjob_list_dir(const char *root,
const bool skip_currpar)
{
struct direntry *files;
- int nbr_files, nbr_entries = 0;
+ int entries_num = 0;
/* Full path of the item. */
char full_path[FILE_MAX];
- nbr_files = BLI_filelist_dir_contents(root, &files);
+ const int files_num = BLI_filelist_dir_contents(root, &files);
if (files) {
- int i = nbr_files;
+ int i = files_num;
while (i--) {
FileListInternEntry *entry;
@@ -3110,11 +3110,11 @@ static int filelist_readjob_list_dir(const char *root,
#endif
BLI_addtail(entries, entry);
- nbr_entries++;
+ entries_num++;
}
- BLI_filelist_free(files, nbr_files);
+ BLI_filelist_free(files, files_num);
}
- return nbr_entries;
+ return entries_num;
}
typedef enum ListLibOptions {
@@ -3370,13 +3370,13 @@ 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.entries_num = 27;
# else
- filelist->filelist.nbr_entries = 26;
+ filelist->filelist.entries_num = 26;
# endif
- filelist_resize(filelist, filelist->filelist.nbr_entries);
+ filelist_resize(filelist, filelist->filelist.entries_num);
- for (a = 0; a < filelist->filelist.nbr_entries; a++) {
+ for (a = 0; a < filelist->filelist.entries_num; a++) {
filelist->filelist.entries[a].typeflag |= FILE_TYPE_DIR;
}
@@ -3419,20 +3419,20 @@ static void filelist_readjob_main_recursive(Main *bmain, FileList *filelist)
return;
}
- filelist->filelist.nbr_entries = 0;
+ filelist->filelist.entries_num = 0;
for (id = lb->first; id; id = id->next) {
if (!(filelist->filter_data.flags & FLF_HIDE_DOT) || id->name[2] != '.') {
- filelist->filelist.nbr_entries++;
+ filelist->filelist.entries_num++;
}
}
/* XXX TODO: if data-browse or append/link #FLF_HIDE_PARENT has to be set. */
if (!(filelist->filter_data.flags & FLF_HIDE_PARENT)) {
- filelist->filelist.nbr_entries++;
+ filelist->filelist.entries_num++;
}
- if (filelist->filelist.nbr_entries > 0) {
- filelist_resize(filelist, filelist->filelist.nbr_entries);
+ if (filelist->filelist.entries_num > 0) {
+ filelist_resize(filelist, filelist->filelist.entries_num);
}
files = filelist->filelist.entries;
@@ -3538,11 +3538,11 @@ typedef struct FileListReadJob {
static void filelist_readjob_append_entries(FileListReadJob *job_params,
ListBase *from_entries,
- int nbr_from_entries,
+ int from_entries_num,
short *do_update)
{
- BLI_assert(BLI_listbase_count(from_entries) == nbr_from_entries);
- if (nbr_from_entries <= 0) {
+ BLI_assert(BLI_listbase_count(from_entries) == from_entries_num);
+ if (from_entries_num <= 0) {
*do_update = false;
return;
}
@@ -3550,7 +3550,7 @@ static void filelist_readjob_append_entries(FileListReadJob *job_params,
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
BLI_mutex_lock(&job_params->lock);
BLI_movelisttolist(&filelist->filelist.entries, from_entries);
- filelist->filelist.nbr_entries += nbr_from_entries;
+ filelist->filelist.entries_num += from_entries_num;
BLI_mutex_unlock(&job_params->lock);
*do_update = true;
@@ -3606,7 +3606,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
char filter_glob[FILE_MAXFILE];
const char *root = filelist->filelist.root;
const int max_recursion = filelist->max_recursion;
- int nbr_done_dirs = 0, nbr_todo_dirs = 1;
+ int dirs_done_count = 0, dirs_todo_count = 1;
todo_dirs = BLI_stack_new(sizeof(*td_dir), __func__);
td_dir = BLI_stack_push_r(todo_dirs);
@@ -3626,7 +3626,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
while (!BLI_stack_is_empty(todo_dirs) && !(*stop)) {
FileListInternEntry *entry;
- int nbr_entries = 0;
+ int entries_num = 0;
char *subdir;
char rel_subdir[FILE_MAX_LIBEXTRA];
@@ -3666,15 +3666,15 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
if (filelist->asset_library_ref) {
list_lib_options |= LIST_LIB_ASSETS_ONLY;
}
- nbr_entries = filelist_readjob_list_lib(
+ entries_num = filelist_readjob_list_lib(
subdir, &entries, list_lib_options, &indexer_runtime);
- if (nbr_entries > 0) {
+ if (entries_num > 0) {
is_lib = true;
}
}
if (!is_lib) {
- nbr_entries = filelist_readjob_list_dir(
+ entries_num = filelist_readjob_list_dir(
subdir, &entries, filter_glob, do_lib, job_params->main_name, skip_currpar);
}
@@ -3698,14 +3698,14 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib,
td_dir = BLI_stack_push_r(todo_dirs);
td_dir->level = recursion_level + 1;
td_dir->dir = BLI_strdup(dir);
- nbr_todo_dirs++;
+ dirs_todo_count++;
}
}
- filelist_readjob_append_entries(job_params, &entries, nbr_entries, do_update);
+ filelist_readjob_append_entries(job_params, &entries, entries_num, do_update);
- nbr_done_dirs++;
- *progress = (float)nbr_done_dirs / (float)nbr_todo_dirs;
+ dirs_done_count++;
+ *progress = (float)dirs_done_count / (float)dirs_todo_count;
MEM_freeN(subdir);
}
@@ -3738,10 +3738,10 @@ static void filelist_readjob_do(const bool do_lib,
// BLI_assert(filelist->filtered == NULL);
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
- (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET));
+ (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
/* A valid, but empty directory from now. */
- filelist->filelist.nbr_entries = 0;
+ filelist->filelist.entries_num = 0;
filelist_readjob_recursive_dir_add_items(do_lib, job_params, stop, do_update, progress);
}
@@ -3812,7 +3812,7 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
FileListInternEntry *entry;
ListBase tmp_entries = {0};
ID *id_iter;
- int nbr_entries = 0;
+ int entries_num = 0;
/* Make sure no IDs are added/removed/reallocated in the main thread while this is running in
* parallel. */
@@ -3835,19 +3835,19 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params,
entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data,
id_iter);
entry->local_data.id = id_iter;
- nbr_entries++;
+ entries_num++;
BLI_addtail(&tmp_entries, entry);
}
FOREACH_MAIN_ID_END;
BKE_main_unlock(job_params->current_main);
- if (nbr_entries) {
+ if (entries_num) {
*do_update = true;
BLI_movelisttolist(&filelist->filelist.entries, &tmp_entries);
- filelist->filelist.nbr_entries += nbr_entries;
- filelist->filelist.nbr_entries_filtered = -1;
+ filelist->filelist.entries_num += entries_num;
+ filelist->filelist.entries_filtered_num = -1;
}
}
@@ -3872,10 +3872,10 @@ static void filelist_readjob_asset_library(FileListReadJob *job_params,
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
- (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET));
+ (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
/* A valid, but empty file-list from now. */
- filelist->filelist.nbr_entries = 0;
+ filelist->filelist.entries_num = 0;
/* NOP if already read. */
filelist_readjob_load_asset_library_data(job_params, do_update);
@@ -3904,12 +3904,12 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params,
{
FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */
BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) &&
- (filelist->filelist.nbr_entries == FILEDIR_NBR_ENTRIES_UNSET));
+ (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET));
filelist_readjob_load_asset_library_data(job_params, do_update);
/* A valid, but empty file-list from now. */
- filelist->filelist.nbr_entries = 0;
+ filelist->filelist.entries_num = 0;
filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress);
}
@@ -3932,7 +3932,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
FileListReadJob *flrj = flrjv;
// printf("START filelist reading (%d files, main thread: %d)\n",
- // flrj->filelist->filelist.nbr_entries, BLI_thread_is_main());
+ // flrj->filelist->filelist.entries_num, BLI_thread_is_main());
BLI_mutex_lock(&flrj->lock);
@@ -3941,7 +3941,7 @@ static void filelist_readjob_startjob(void *flrjv, short *stop, short *do_update
flrj->tmp_filelist = MEM_dupallocN(flrj->filelist);
BLI_listbase_clear(&flrj->tmp_filelist->filelist.entries);
- flrj->tmp_filelist->filelist.nbr_entries = FILEDIR_NBR_ENTRIES_UNSET;
+ flrj->tmp_filelist->filelist.entries_num = FILEDIR_NBR_ENTRIES_UNSET;
flrj->tmp_filelist->filelist_intern.filtered = NULL;
BLI_listbase_clear(&flrj->tmp_filelist->filelist_intern.entries);
@@ -3973,18 +3973,18 @@ static void filelist_readjob_update(void *flrjv)
FileListReadJob *flrj = flrjv;
FileListIntern *fl_intern = &flrj->filelist->filelist_intern;
ListBase new_entries = {NULL};
- int nbr_entries, new_nbr_entries = 0;
+ int entries_num, new_entries_num = 0;
BLI_movelisttolist(&new_entries, &fl_intern->entries);
- nbr_entries = flrj->filelist->filelist.nbr_entries;
+ entries_num = flrj->filelist->filelist.entries_num;
BLI_mutex_lock(&flrj->lock);
- if (flrj->tmp_filelist->filelist.nbr_entries > 0) {
+ if (flrj->tmp_filelist->filelist.entries_num > 0) {
/* We just move everything out of 'thread context' into final list. */
- new_nbr_entries = flrj->tmp_filelist->filelist.nbr_entries;
+ new_entries_num = flrj->tmp_filelist->filelist.entries_num;
BLI_movelisttolist(&new_entries, &flrj->tmp_filelist->filelist.entries);
- flrj->tmp_filelist->filelist.nbr_entries = 0;
+ flrj->tmp_filelist->filelist.entries_num = 0;
}
if (flrj->tmp_filelist->asset_library) {
@@ -3998,7 +3998,7 @@ static void filelist_readjob_update(void *flrjv)
BLI_mutex_unlock(&flrj->lock);
- if (new_nbr_entries) {
+ if (new_entries_num) {
/* Do not clear selection cache, we can assume already 'selected' UIDs are still valid! Keep
* the asset library data we just read. */
filelist_clear_ex(flrj->filelist, false, true, false);
@@ -4006,9 +4006,9 @@ static void filelist_readjob_update(void *flrjv)
flrj->filelist->flags |= (FL_NEED_SORTING | FL_NEED_FILTERING);
}
- /* if no new_nbr_entries, this is NOP */
+ /* if no new_entries_num, this is NOP */
BLI_movelisttolist(&fl_intern->entries, &new_entries);
- flrj->filelist->filelist.nbr_entries = MAX2(nbr_entries, 0) + new_nbr_entries;
+ flrj->filelist->filelist.entries_num = MAX2(entries_num, 0) + new_entries_num;
}
static void filelist_readjob_endjob(void *flrjv)
@@ -4026,11 +4026,11 @@ static void filelist_readjob_free(void *flrjv)
{
FileListReadJob *flrj = flrjv;
- // printf("END filelist reading (%d files)\n", flrj->filelist->filelist.nbr_entries);
+ // printf("END filelist reading (%d files)\n", flrj->filelist->filelist.entries_num);
if (flrj->tmp_filelist) {
/* tmp_filelist shall never ever be filtered! */
- BLI_assert(flrj->tmp_filelist->filelist.nbr_entries == 0);
+ BLI_assert(flrj->tmp_filelist->filelist.entries_num == 0);
BLI_assert(BLI_listbase_is_empty(&flrj->tmp_filelist->filelist.entries));
filelist_freelib(flrj->tmp_filelist);
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 847bf89bba8..ae0e5b23d55 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -968,13 +968,13 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
/* Check gvfs shares. */
const char *const xdg_runtime_dir = BLI_getenv("XDG_RUNTIME_DIR");
if (xdg_runtime_dir != NULL) {
- struct direntry *dir;
+ struct direntry *dirs;
char name[FILE_MAX];
BLI_join_dirfile(name, sizeof(name), xdg_runtime_dir, "gvfs/");
- const uint dir_len = BLI_filelist_dir_contents(name, &dir);
- for (uint i = 0; i < dir_len; i++) {
- if (dir[i].type & S_IFDIR) {
- const char *dirname = dir[i].relname;
+ const uint dirs_num = BLI_filelist_dir_contents(name, &dirs);
+ for (uint i = 0; i < dirs_num; i++) {
+ if (dirs[i].type & S_IFDIR) {
+ const char *dirname = dirs[i].relname;
if (dirname[0] != '.') {
/* Dir names contain a lot of unwanted text.
* Assuming every entry ends with the share name */
@@ -992,7 +992,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
}
}
}
- BLI_filelist_free(dir, dir_len);
+ BLI_filelist_free(dirs, dirs_num);
}
# endif
diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt
index f5cc6083b25..c385420b18e 100644
--- a/source/blender/editors/space_image/CMakeLists.txt
+++ b/source/blender/editors/space_image/CMakeLists.txt
@@ -60,6 +60,9 @@ if(WITH_IMAGE_CINEON)
add_definitions(-DWITH_CINEON)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
blender_add_lib(bf_editor_space_image "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 1c4a1d7e8c9..aa77aab2283 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2790,8 +2790,7 @@ static int image_flip_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* force GPU re-upload, all image is invalid. */
- BKE_image_free_gputextures(ima);
+ BKE_image_partial_update_mark_full_update(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2910,8 +2909,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* Force GPU re-upload, all image is invalid. */
- BKE_image_free_gputextures(ima);
+ BKE_image_partial_update_mark_full_update(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -3001,8 +2999,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
- /* Force GPU re-upload, all image is invalid. */
- BKE_image_free_gputextures(ima);
+ BKE_image_partial_update_mark_full_update(ima);
DEG_id_tag_update(&ima->id, 0);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc
index 716d5b67fe3..a4ff44512ef 100644
--- a/source/blender/editors/space_outliner/outliner_collections.cc
+++ b/source/blender/editors/space_outliner/outliner_collections.cc
@@ -301,7 +301,7 @@ static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *c
if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(collection)) {
- if (!data->is_liboverride_hierarchy_root_allowed) {
+ if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
return TRAVERSE_SKIP_CHILDS;
}
}
diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc
index 8b03047b1dd..9857abb3da7 100644
--- a/source/blender/editors/space_outliner/outliner_draw.cc
+++ b/source/blender/editors/space_outliner/outliner_draw.cc
@@ -3917,6 +3917,7 @@ void draw_outliner(const bContext *C)
block, region, space_outliner, &space_outliner->tree, true);
UI_block_emboss_set(block, UI_EMBOSS);
+ UI_block_flag_enable(block, UI_BLOCK_NO_DRAW_OVERRIDDEN_STATE);
const int x = region->v2d.cur.xmax - right_column_width;
outliner_draw_separator(region, x);
outliner_draw_overrides_rna_buts(block, region, space_outliner, &space_outliner->tree, x);
diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc
index a60e082f6a5..ae67e7108bf 100644
--- a/source/blender/editors/space_outliner/outliner_edit.cc
+++ b/source/blender/editors/space_outliner/outliner_edit.cc
@@ -447,6 +447,17 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto
(tselem->type == TSE_LAYER_COLLECTION));
UNUSED_VARS_NDEBUG(te);
+ if (ID_IS_OVERRIDE_LIBRARY(id)) {
+ if (!ID_IS_OVERRIDE_LIBRARY_REAL(id) ||
+ (id->override_library->flag & IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY) == 0) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete library override id '%s', it is part of an override hierarchy",
+ id->name);
+ return;
+ }
+ }
+
if (te->idcode == ID_LI && ((Library *)id)->parent != nullptr) {
BKE_reportf(reports, RPT_WARNING, "Cannot delete indirectly linked library '%s'", id->name);
return;
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index 612baaa0752..0aea4521204 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -1677,6 +1677,12 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot)
using OutlinerDeleteFn = void (*)(bContext *C, ReportList *reports, Scene *scene, Object *ob);
+typedef struct ObjectEditData {
+ GSet *objects_set;
+ bool is_liboverride_allowed;
+ bool is_liboverride_hierarchy_root_allowed;
+} ObjectEditData;
+
static void outliner_do_object_delete(bContext *C,
ReportList *reports,
Scene *scene,
@@ -1693,7 +1699,8 @@ static void outliner_do_object_delete(bContext *C,
static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata)
{
- GSet *objects_to_delete = (GSet *)customdata;
+ ObjectEditData *data = reinterpret_cast<ObjectEditData *>(customdata);
+ GSet *objects_to_delete = data->objects_set;
TreeStoreElem *tselem = TREESTORE(te);
if (outliner_is_collection_tree_element(te)) {
@@ -1708,9 +1715,15 @@ static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void
ID *id = tselem->id;
if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
- if (!ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(id)) {
- /* Only allow deletion of liboverride objects if they are root overrides. */
- return TRAVERSE_SKIP_CHILDS;
+ if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(id)) {
+ if (!(data->is_liboverride_hierarchy_root_allowed || data->is_liboverride_allowed)) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
+ }
+ else {
+ if (!data->is_liboverride_allowed) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
}
}
@@ -1732,27 +1745,31 @@ static int outliner_delete_exec(bContext *C, wmOperator *op)
/* Get selected objects skipping duplicates to prevent deleting objects linked to multiple
* collections twice */
- GSet *objects_to_delete = BLI_gset_ptr_new(__func__);
+ ObjectEditData object_delete_data = {};
+ object_delete_data.objects_set = BLI_gset_ptr_new(__func__);
+ object_delete_data.is_liboverride_allowed = false;
+ object_delete_data.is_liboverride_hierarchy_root_allowed = delete_hierarchy;
outliner_tree_traverse(space_outliner,
&space_outliner->tree,
0,
TSE_SELECTED,
outliner_find_objects_to_delete,
- objects_to_delete);
+ &object_delete_data);
if (delete_hierarchy) {
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
outliner_do_object_delete(
- C, op->reports, scene, objects_to_delete, object_batch_delete_hierarchy_fn);
+ C, op->reports, scene, object_delete_data.objects_set, object_batch_delete_hierarchy_fn);
BKE_id_multi_tagged_delete(bmain);
}
else {
- outliner_do_object_delete(C, op->reports, scene, objects_to_delete, outliner_object_delete_fn);
+ outliner_do_object_delete(
+ C, op->reports, scene, object_delete_data.objects_set, outliner_object_delete_fn);
}
- BLI_gset_free(objects_to_delete, nullptr);
+ BLI_gset_free(object_delete_data.objects_set, nullptr);
outliner_collection_delete(C, bmain, scene, op->reports, delete_hierarchy);
diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc
index 1a772287dfa..19fe40b612e 100644
--- a/source/blender/editors/space_outliner/outliner_tree.cc
+++ b/source/blender/editors/space_outliner/outliner_tree.cc
@@ -900,7 +900,6 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
/* ID types not (fully) ported to new design yet. */
if (te->abstract_element->expandPoll(*space_outliner)) {
outliner_add_id_contents(space_outliner, te, tselem, id);
- te->abstract_element->postExpand(*space_outliner);
}
}
else if (ELEM(type,
diff --git a/source/blender/editors/space_outliner/tree/tree_display.hh b/source/blender/editors/space_outliner/tree/tree_display.hh
index bdca1954a9c..a60d3339042 100644
--- a/source/blender/editors/space_outliner/tree/tree_display.hh
+++ b/source/blender/editors/space_outliner/tree/tree_display.hh
@@ -136,8 +136,7 @@ class TreeDisplayOverrideLibrary final : public AbstractTreeDisplay {
ListBase buildTree(const TreeSourceData &source_data) override;
private:
- TreeElement *add_library_contents(Main &, ListBase &, Library *);
- bool override_library_id_filter_poll(const Library *lib, ID *id) const;
+ ListBase add_library_contents(Main &);
short id_filter_get() const;
};
diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
index 0023b7c7b62..476bbdb63ae 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc
@@ -150,7 +150,7 @@ TreeElement *TreeDisplayLibraries::add_library_contents(Main &mainvar, ListBase
}
else {
ten = outliner_add_element(
- &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0);
+ &space_outliner_, &tenlib->subtree, lib, nullptr, TSE_ID_BASE, a);
ten->directdata = lbarray[a];
ten->name = outliner_idcode_to_plural(GS(id->name));
}
diff --git a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
index f94727ba356..2162c303da1 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_override_library.cc
@@ -32,72 +32,22 @@ TreeDisplayOverrideLibrary::TreeDisplayOverrideLibrary(SpaceOutliner &space_outl
ListBase TreeDisplayOverrideLibrary::buildTree(const TreeSourceData &source_data)
{
- ListBase tree = {nullptr};
-
- {
- /* current file first - mainvar provides tselem with unique pointer - not used */
- TreeElement *ten = add_library_contents(*source_data.bmain, tree, nullptr);
- TreeStoreElem *tselem;
-
- if (ten) {
- tselem = TREESTORE(ten);
- if (!tselem->used) {
- tselem->flag &= ~TSE_CLOSED;
- }
- }
- }
+ ListBase tree = add_library_contents(*source_data.bmain);
- for (ID *id : List<ID>(source_data.bmain->libraries)) {
- Library *lib = reinterpret_cast<Library *>(id);
- TreeElement *ten = add_library_contents(*source_data.bmain, tree, lib);
- /* NULL-check matters, due to filtering there may not be a new element. */
- if (ten) {
- lib->id.newid = (ID *)ten;
+ for (TreeElement *top_level_te : List<TreeElement>(tree)) {
+ TreeStoreElem *tselem = TREESTORE(top_level_te);
+ if (!tselem->used) {
+ tselem->flag &= ~TSE_CLOSED;
}
}
- /* make hierarchy */
- for (TreeElement *ten : List<TreeElement>(tree)) {
- if (ten == tree.first) {
- /* First item is main, skip. */
- continue;
- }
-
- TreeStoreElem *tselem = TREESTORE(ten);
- Library *lib = (Library *)tselem->id;
- BLI_assert(!lib || (GS(lib->id.name) == ID_LI));
- if (!lib || !lib->parent) {
- continue;
- }
-
- TreeElement *parent = (TreeElement *)lib->parent->id.newid;
-
- if (tselem->id->tag & LIB_TAG_INDIRECT) {
- /* Only remove from 'first level' if lib is not also directly used. */
- BLI_remlink(&tree, ten);
- BLI_addtail(&parent->subtree, ten);
- ten->parent = parent;
- }
- else {
- /* Else, make a new copy of the libtree for our parent. */
- TreeElement *dupten = add_library_contents(*source_data.bmain, parent->subtree, lib);
- if (dupten) {
- dupten->parent = parent;
- }
- }
- }
- /* restore newid pointers */
- for (ID *library_id : List<ID>(source_data.bmain->libraries)) {
- library_id->newid = nullptr;
- }
-
return tree;
}
-TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar,
- ListBase &lb,
- Library *lib)
+ListBase TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar)
{
+ ListBase tree = {nullptr};
+
const short filter_id_type = id_filter_get();
ListBase *lbarray[INDEX_ID_MAX];
@@ -110,7 +60,6 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar,
tot = set_listbasepointers(&mainvar, lbarray);
}
- TreeElement *tenlib = nullptr;
for (int a = 0; a < tot; a++) {
if (!lbarray[a] || !lbarray[a]->first) {
continue;
@@ -118,56 +67,51 @@ TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar,
ID *id = nullptr;
- /* check if there's data in current lib */
+ /* check if there's data in current id list */
for (ID *id_iter : List<ID>(lbarray[a])) {
- if (id_iter->lib == lib && ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) && !ID_IS_LINKED(id_iter)) {
id = id_iter;
break;
}
}
- if (id != nullptr) {
- if (!tenlib) {
- /* Create library tree element on demand, depending if there are any data-blocks. */
- if (lib) {
- tenlib = outliner_add_element(&space_outliner_, &lb, lib, nullptr, TSE_SOME_ID, 0);
- }
- else {
- tenlib = outliner_add_element(&space_outliner_, &lb, &mainvar, nullptr, TSE_ID_BASE, 0);
- tenlib->name = IFACE_("Current File");
- }
- if (tenlib->flag & TE_HAS_WARNING) {
- has_warnings = true;
- }
- }
+ if (id == nullptr) {
+ continue;
+ }
- /* Create data-block list parent element on demand. */
- TreeElement *ten;
+ /* Create data-block list parent element on demand. */
+ TreeElement *id_base_te = nullptr;
+ ListBase *lb_to_expand = &tree;
- if (filter_id_type) {
- ten = tenlib;
- }
- else {
- ten = outliner_add_element(
- &space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0);
- ten->directdata = lbarray[a];
- ten->name = outliner_idcode_to_plural(GS(id->name));
- }
+ if (!filter_id_type) {
+ id_base_te = outliner_add_element(
+ &space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0);
+ id_base_te->directdata = lbarray[a];
+ id_base_te->name = outliner_idcode_to_plural(GS(id->name));
- for (ID *id : List<ID>(lbarray[a])) {
- if (override_library_id_filter_poll(lib, id)) {
- TreeElement *override_tree_element = outliner_add_element(
- &space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
+ lb_to_expand = &id_base_te->subtree;
+ }
- if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
- outliner_free_tree_element(override_tree_element, &ten->subtree);
- }
+ for (ID *id : List<ID>(lbarray[a])) {
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id)) {
+ TreeElement *override_tree_element = outliner_add_element(
+ &space_outliner_, lb_to_expand, id, id_base_te, TSE_LIBRARY_OVERRIDE_BASE, 0);
+
+ if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
+ outliner_free_tree_element(override_tree_element, lb_to_expand);
}
}
}
}
- return tenlib;
+ /* Remove ID base elements that turn out to be empty. */
+ LISTBASE_FOREACH_MUTABLE (TreeElement *, te, &tree) {
+ if (BLI_listbase_is_empty(&te->subtree)) {
+ outliner_free_tree_element(te, &tree);
+ }
+ }
+
+ return tree;
}
short TreeDisplayOverrideLibrary::id_filter_get() const
@@ -178,17 +122,4 @@ short TreeDisplayOverrideLibrary::id_filter_get() const
return 0;
}
-bool TreeDisplayOverrideLibrary::override_library_id_filter_poll(const Library *lib, ID *id) const
-{
- if (id->lib != lib) {
- return false;
- }
-
- if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
- return false;
- }
-
- return true;
-}
-
} // namespace blender::ed::outliner
diff --git a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
index 0ee5059a54d..19811e45b90 100644
--- a/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
+++ b/source/blender/editors/space_outliner/tree/tree_display_view_layer.cc
@@ -154,15 +154,6 @@ void TreeDisplayViewLayer::add_layer_collections_recursive(ListBase &tree,
if (!exclude && show_objects_) {
add_layer_collection_objects(ten->subtree, *lc, *ten);
}
-
- const bool lib_overrides_visible = !exclude && (!SUPPORT_FILTER_OUTLINER(&space_outliner_) ||
- ((space_outliner_.filter &
- SO_FILTER_NO_LIB_OVERRIDE) == 0));
-
- if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&lc->collection->id)) {
- outliner_add_element(
- &space_outliner_, &ten->subtree, &lc->collection->id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
- }
}
}
diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc
index 3c2023d7905..ca67aad00db 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element.cc
@@ -107,7 +107,6 @@ void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner
return;
}
tree_element.expand(space_outliner);
- tree_element.postExpand(space_outliner);
}
bool tree_element_warnings_get(TreeElement *te, int *r_icon, const char **r_message)
diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh
index 2fbc86705b9..6f2d803ae96 100644
--- a/source/blender/editors/space_outliner/tree/tree_element.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element.hh
@@ -40,9 +40,6 @@ class AbstractTreeElement {
{
return true;
}
- virtual void postExpand(SpaceOutliner &) const
- {
- }
/**
* Just while transitioning to the new tree-element design: Some types are only partially ported,
diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.cc b/source/blender/editors/space_outliner/tree/tree_element_id.cc
index 64c73f57107..ef5e056f229 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_id.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_id.cc
@@ -93,17 +93,6 @@ TreeElementID::TreeElementID(TreeElement &legacy_te, ID &id)
legacy_te_.idcode = GS(id.name);
}
-void TreeElementID::postExpand(SpaceOutliner &space_outliner) const
-{
- const bool lib_overrides_visible = !SUPPORT_FILTER_OUTLINER(&space_outliner) ||
- ((space_outliner.filter & SO_FILTER_NO_LIB_OVERRIDE) == 0);
-
- if (lib_overrides_visible && ID_IS_OVERRIDE_LIBRARY_REAL(&id_)) {
- outliner_add_element(
- &space_outliner, &legacy_te_.subtree, &id_, &legacy_te_, TSE_LIBRARY_OVERRIDE_BASE, 0);
- }
-}
-
bool TreeElementID::expandPoll(const SpaceOutliner &space_outliner) const
{
const TreeStoreElem *tsepar = legacy_te_.parent ? TREESTORE(legacy_te_.parent) : nullptr;
diff --git a/source/blender/editors/space_outliner/tree/tree_element_id.hh b/source/blender/editors/space_outliner/tree/tree_element_id.hh
index 75dc7e737e2..b7519fe06f9 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_id.hh
+++ b/source/blender/editors/space_outliner/tree/tree_element_id.hh
@@ -24,7 +24,6 @@ class TreeElementID : public AbstractTreeElement {
static std::unique_ptr<TreeElementID> createFromID(TreeElement &legacy_te, ID &id);
- void postExpand(SpaceOutliner &) const override;
bool expandPoll(const SpaceOutliner &) const override;
/**
diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
index abc7cd8f8ce..914104f1f06 100644
--- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc
+++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc
@@ -52,7 +52,7 @@ bool TreeElementRNACommon::isRNAValid() const
return rna_ptr_.data != nullptr;
}
-bool TreeElementRNACommon::expandPoll(const SpaceOutliner &) const
+bool TreeElementRNACommon::expandPoll(const SpaceOutliner &UNUSED(space_outliner)) const
{
return isRNAValid();
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 3ccdf701a86..283bd99cd5d 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -1643,35 +1643,6 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot)
/** \name Duplicate Strips Operator
* \{ */
-static void sequencer_backup_original_animation(Scene *scene, ListBase *list)
-{
- if (scene->adt == NULL || scene->adt->action == NULL ||
- BLI_listbase_is_empty(&scene->adt->action->curves)) {
- return;
- }
-
- BLI_movelisttolist(list, &scene->adt->action->curves);
-}
-
-static void sequencer_restore_original_animation(Scene *scene, ListBase *list)
-{
- if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) {
- return;
- }
-
- BLI_movelisttolist(&scene->adt->action->curves, list);
-}
-
-static void sequencer_duplicate_animation(Scene *scene, Sequence *seq, ListBase *curves_backup)
-{
- GSet *fcurves = SEQ_fcurves_by_strip_get(seq, curves_backup);
- GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
- FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
- BLI_addtail(&scene->adt->action->curves, fcu_cpy);
- }
- GSET_FOREACH_END();
-}
-
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
@@ -1697,7 +1668,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
* original curves from backup.
*/
ListBase fcurves_original_backup = {NULL, NULL};
- sequencer_backup_original_animation(scene, &fcurves_original_backup);
+ SEQ_animation_backup_original(scene, &fcurves_original_backup);
Sequence *seq = duplicated_strips.first;
@@ -1712,11 +1683,11 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
SEQ_select_active_set(scene, seq);
}
seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
- sequencer_duplicate_animation(scene, seq, &fcurves_original_backup);
+ SEQ_animation_duplicate(scene, seq, &fcurves_original_backup);
SEQ_ensure_unique_name(seq, scene);
}
- sequencer_restore_original_animation(scene, &fcurves_original_backup);
+ SEQ_animation_restore_original(scene, &fcurves_original_backup);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -2622,7 +2593,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
*/
ListBase fcurves_original_backup = {NULL, NULL};
- sequencer_backup_original_animation(scene, &fcurves_original_backup);
+ SEQ_animation_backup_original(scene, &fcurves_original_backup);
sequencer_paste_animation(C);
/* Copy strips, temporarily restoring pointers to actual data-blocks. This
@@ -2654,7 +2625,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op)
}
}
- sequencer_restore_original_animation(scene, &fcurves_original_backup);
+ SEQ_animation_restore_original(scene, &fcurves_original_backup);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
DEG_relations_tag_update(bmain);
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 15fea301b1c..f5656e13c0e 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -165,7 +165,7 @@ BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x)
static bool text_new_poll(bContext *UNUSED(C))
{
- return 1;
+ return true;
}
static bool text_data_poll(bContext *C)
@@ -182,15 +182,15 @@ static bool text_edit_poll(bContext *C)
Text *text = CTX_data_edit_text(C);
if (!text) {
- return 0;
+ return false;
}
if (ID_IS_LINKED(text)) {
// BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
bool text_space_edit_poll(bContext *C)
@@ -199,15 +199,15 @@ bool text_space_edit_poll(bContext *C)
Text *text = CTX_data_edit_text(C);
if (!st || !text) {
- return 0;
+ return false;
}
if (ID_IS_LINKED(text)) {
// BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static bool text_region_edit_poll(bContext *C)
@@ -217,19 +217,19 @@ static bool text_region_edit_poll(bContext *C)
ARegion *region = CTX_wm_region(C);
if (!st || !text) {
- return 0;
+ return false;
}
if (!region || region->regiontype != RGN_TYPE_WINDOW) {
- return 0;
+ return false;
}
if (ID_IS_LINKED(text)) {
// BKE_report(op->reports, RPT_ERROR, "Cannot edit external library data");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c
index 53f7b3d5871..f3e45a14565 100644
--- a/source/blender/editors/space_view3d/view3d_cursor_snap.c
+++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c
@@ -620,9 +620,6 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
snap_elements &= ~SCE_SNAP_MODE_EDGE_PERPENDICULAR;
}
- eSnapSelect snap_select = (state->flag & V3D_SNAPCURSOR_SNAP_ONLY_ACTIVE) ? SNAP_ONLY_ACTIVE :
- SNAP_ALL;
-
eSnapEditType edit_mode_type = (state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_FINAL) ?
SNAP_GEOM_FINAL :
(state->flag & V3D_SNAPCURSOR_SNAP_EDIT_GEOM_CAGE) ?
@@ -640,7 +637,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
v3d,
snap_elements,
&(const struct SnapObjectParams){
- .snap_select = snap_select,
+ .snap_select = SNAP_ALL,
.edit_mode_type = edit_mode_type,
.use_occlusion_test = use_occlusion_test,
},
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 6f55acff6a2..30282df8026 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -2049,6 +2049,40 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc,
}
/**
+ * Compare result of 'GPU_select': 'GPUSelectResult',
+ * Needed for stable sorting, so cycling through all items near the cursor behaves predictably.
+ */
+static int gpu_select_buffer_depth_id_cmp(const void *sel_a_p, const void *sel_b_p)
+{
+ GPUSelectResult *a = (GPUSelectResult *)sel_a_p;
+ GPUSelectResult *b = (GPUSelectResult *)sel_b_p;
+
+ if (a->depth < b->depth) {
+ return -1;
+ }
+ if (a->depth > b->depth) {
+ return 1;
+ }
+
+ /* Depths match, sort by id. */
+ uint sel_a = a->id;
+ uint sel_b = b->id;
+
+#ifdef __BIG_ENDIAN__
+ BLI_endian_switch_uint32(&sel_a);
+ BLI_endian_switch_uint32(&sel_b);
+#endif
+
+ if (sel_a < sel_b) {
+ return -1;
+ }
+ if (sel_a > sel_b) {
+ return 1;
+ }
+ return 0;
+}
+
+/**
* \param has_bones: When true, skip non-bone hits, also allow bases to be used
* that are visible but not select-able,
* since you may be in pose mode with an un-selectable object.
@@ -2058,36 +2092,40 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc,
static Base *mouse_select_eval_buffer(ViewContext *vc,
const GPUSelectResult *buffer,
int hits,
- Base *startbase,
- bool has_bones,
bool do_nearest,
- int *r_sub_selection)
+ bool has_bones,
+ bool do_bones_get_priotity,
+ int *r_select_id_subelem)
{
ViewLayer *view_layer = vc->view_layer;
View3D *v3d = vc->v3d;
- Base *base, *basact = NULL;
int a;
- int sub_selection_id = 0;
+
+ bool found = false;
+ int select_id = 0;
+ int select_id_subelem = 0;
if (do_nearest) {
uint min = 0xFFFFFFFF;
- int selcol = 0;
+ int hit_index = -1;
- if (has_bones) {
+ if (has_bones && do_bones_get_priotity) {
/* we skip non-bone hits */
for (a = 0; a < hits; a++) {
if (min > buffer[a].depth && (buffer[a].id & 0xFFFF0000)) {
min = buffer[a].depth;
- selcol = buffer[a].id & 0xFFFF;
- sub_selection_id = (buffer[a].id & 0xFFFF0000) >> 16;
+ hit_index = a;
}
}
}
else {
- int select_id_exclude = 0;
- /* Only exclude active object when it is selected. */
- if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED) && hits > 1) {
- select_id_exclude = BASACT(view_layer)->object->runtime.select_id;
+
+ for (a = 0; a < hits; a++) {
+ /* Any object. */
+ if (min > buffer[a].depth) {
+ min = buffer[a].depth;
+ hit_index = a;
+ }
}
/* Find the best active & non-active hits.
@@ -2099,102 +2137,111 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
*
* For this reason, keep track of the best hit as well as the best hit that
* excludes the selected & active object, using this value when it's valid. */
+ if ((hit_index != -1) &&
+ /* Special case, cycling away from the active object should only be done when it
+ * doesn't have a bone selection, otherwise selecting sub-elements is difficult. */
+ ((buffer[hit_index].id & 0xFFFF0000) == 0) &&
+ /* Only exclude active object when it is selected. */
+ (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED)) &&
+ /* Allow disabling this behavior entirely. */
+ (U.experimental.use_select_nearest_on_first_click == false)) {
+
+ const int select_id_active = BASACT(view_layer)->object->runtime.select_id;
+
+ /* Check if `hit_index` is the current active object. */
+ if ((buffer[hit_index].id & 0xFFFF) == select_id_active) {
+ uint min_not_active = 0xFFFFFFFF;
+ int hit_index_not_active = -1;
+ for (a = 0; a < hits; a++) {
+ /* Any object other than the active-selected. */
+ if (select_id_active == (buffer[a].id & 0xFFFF)) {
+ continue;
+ }
+ if (min_not_active > buffer[a].depth) {
+ min_not_active = buffer[a].depth;
+ hit_index_not_active = a;
+ }
+ }
- uint min_not_active = min;
- int hit_index = -1, hit_index_not_active = -1;
-
- for (a = 0; a < hits; a++) {
- /* Any object. */
- if (min > buffer[a].depth) {
- min = buffer[a].depth;
- hit_index = a;
- }
- /* Any object other than the active-selected. */
- if (select_id_exclude != 0) {
- if (min_not_active > buffer[a].depth && select_id_exclude != (buffer[a].id & 0xFFFF)) {
- min_not_active = buffer[a].depth;
- hit_index_not_active = a;
+ /* When the active was selected, first try to use the index
+ * for the best non-active hit that was found. */
+ if (hit_index_not_active != -1) {
+ hit_index = hit_index_not_active;
}
}
}
-
- /* When the active was selected, first try to use the index
- * for the best non-active hit that was found. */
- if (hit_index_not_active != -1) {
- hit_index = hit_index_not_active;
- }
-
- if (hit_index != -1) {
- selcol = buffer[hit_index].id & 0xFFFF;
- sub_selection_id = (buffer[hit_index].id & 0xFFFF0000) >> 16;
- /* No need to set `min` to `buffer[hit_index].depth`, it's not used from now on. */
- }
}
- base = FIRSTBASE(view_layer);
- while (base) {
- if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) {
- if (base->object->runtime.select_id == selcol) {
- break;
- }
- }
- base = base->next;
- }
- if (base) {
- basact = base;
+ if (hit_index != -1) {
+ select_id = buffer[hit_index].id & 0xFFFF;
+ select_id_subelem = (buffer[hit_index].id & 0xFFFF0000) >> 16;
+ found = true;
+ /* No need to set `min` to `buffer[hit_index].depth`, it's not used from now on. */
}
}
else {
- base = startbase;
- while (base) {
- /* skip objects with select restriction, to prevent prematurely ending this loop
- * with an un-selectable choice */
- if (has_bones ? (base->flag & BASE_VISIBLE_VIEWLAYER) == 0 :
- (base->flag & BASE_SELECTABLE) == 0) {
- base = base->next;
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
+ {
+ GPUSelectResult *buffer_sorted = MEM_mallocN(sizeof(*buffer_sorted) * hits, __func__);
+ memcpy(buffer_sorted, buffer, sizeof(*buffer_sorted) * hits);
+ /* Remove non-bone objects. */
+ if (has_bones && do_bones_get_priotity) {
+ /* Loop backwards to reduce re-ordering. */
+ for (a = hits - 1; a >= 0; a--) {
+ if ((buffer_sorted[a].id & 0xFFFF0000) == 0) {
+ buffer_sorted[a] = buffer_sorted[--hits];
+ }
}
}
+ qsort(buffer_sorted, hits, sizeof(GPUSelectResult), gpu_select_buffer_depth_id_cmp);
+ buffer = buffer_sorted;
+ }
- if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) {
- for (a = 0; a < hits; a++) {
- if (has_bones) {
- /* skip non-bone objects */
- if (buffer[a].id & 0xFFFF0000) {
- if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) {
- basact = base;
- }
- }
- }
- else {
- if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) {
- basact = base;
- }
+ int hit_index = -1;
+
+ /* It's possible there are no hits (all objects contained bones). */
+ if (hits > 0) {
+ /* Only exclude active object when it is selected. */
+ if (BASACT(view_layer) && (BASACT(view_layer)->flag & BASE_SELECTED)) {
+ const int select_id_active = BASACT(view_layer)->object->runtime.select_id;
+ for (int i_next = 0, i_prev = hits - 1; i_next < hits; i_prev = i_next++) {
+ if ((select_id_active == (buffer[i_prev].id & 0xFFFF)) &&
+ (select_id_active != (buffer[i_next].id & 0xFFFF))) {
+ hit_index = i_next;
+ break;
}
}
}
- if (basact) {
- break;
+ /* When the active object is unselected or not in `buffer`, use the nearest. */
+ if (hit_index == -1) {
+ /* Just pick the nearest. */
+ hit_index = 0;
}
+ }
- base = base->next;
- if (base == NULL) {
- base = FIRSTBASE(view_layer);
- }
- if (base == startbase) {
- break;
- }
+ if (hit_index != -1) {
+ select_id = buffer[hit_index].id & 0xFFFF;
+ select_id_subelem = (buffer[hit_index].id & 0xFFFF0000) >> 16;
+ found = true;
}
+ MEM_freeN((void *)buffer);
}
- if (basact && r_sub_selection) {
- *r_sub_selection = sub_selection_id;
+ Base *basact = NULL;
+ if (found) {
+ for (Base *base = FIRSTBASE(view_layer); base; base = base->next) {
+ if (has_bones ? BASE_VISIBLE(v3d, base) : BASE_SELECTABLE(v3d, base)) {
+ if (base->object->runtime.select_id == select_id) {
+ basact = base;
+ break;
+ }
+ }
+ }
+
+ if (basact && r_select_id_subelem) {
+ *r_select_id_subelem = select_id_subelem;
+ }
}
return basact;
@@ -2271,13 +2318,8 @@ static Base *ed_view3d_give_base_under_cursor_ex(bContext *C,
if (hits > 0) {
const bool has_bones = (r_material_slot == NULL) && selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(&vc,
- buffer,
- hits,
- vc.view_layer->object_bases.first,
- has_bones,
- do_nearest,
- r_material_slot);
+ basact = mouse_select_eval_buffer(
+ &vc, buffer, hits, do_nearest, has_bones, true, r_material_slot);
}
return basact;
@@ -2560,11 +2602,27 @@ static bool ed_object_select_pick(bContext *C,
basact = basact_override;
}
else {
- basact =
- (gpu->hits > 0) ?
- mouse_select_eval_buffer(
- &vc, gpu->buffer, gpu->hits, startbase, gpu->has_bones, gpu->do_nearest, NULL) :
- NULL;
+ /* Regarding bone priority.
+ *
+ * - When in pose-bone, it's useful that any selection containing a bone
+ * gets priority over other geometry (background scenery for example).
+ *
+ * - When in object-mode, don't prioritize bones as it would cause
+ * pose-objects behind other objects to get priority
+ * (mainly noticeable when #SCE_OBJECT_MODE_LOCK is disabled).
+ *
+ * This way prioritizing based on pose-mode has a bias to stay in pose-mode
+ * without having to enforce this through locking the object mode. */
+ bool do_bones_get_priotity = (object_mode & OB_MODE_POSE) != 0;
+
+ basact = (gpu->hits > 0) ? mouse_select_eval_buffer(&vc,
+ gpu->buffer,
+ gpu->hits,
+ gpu->do_nearest,
+ gpu->has_bones,
+ do_bones_get_priotity,
+ NULL) :
+ NULL;
}
/* Select pose-bones or camera-tracks. */
@@ -2587,7 +2645,7 @@ static bool ed_object_select_pick(bContext *C,
/* Fallback to regular object selection if no new bundles were selected,
* allows to select object parented to reconstruction object. */
basact = mouse_select_eval_buffer(
- &vc, gpu->buffer, gpu->hits, startbase, false, gpu->do_nearest, NULL);
+ &vc, gpu->buffer, gpu->hits, gpu->do_nearest, false, false, NULL);
}
}
}
@@ -2689,6 +2747,11 @@ static bool ed_object_select_pick(bContext *C,
if (params->sel_op == SEL_OP_SET) {
if ((found && params->select_passthrough) && (basact->flag & BASE_SELECTED)) {
found = false;
+ /* NOTE(@campbellbarton): Experimental behavior to set active even keeping the selection
+ * without this it's inconvenient to set the active object. */
+ if (basact != oldbasact) {
+ use_activate_selected_base = true;
+ }
}
else if (found || params->deselect_all) {
/* Deselect everything. */
diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt
index c8033d9d767..68c4f4e76ca 100644
--- a/source/blender/editors/transform/CMakeLists.txt
+++ b/source/blender/editors/transform/CMakeLists.txt
@@ -90,7 +90,7 @@ set(SRC
transform_orientations.c
transform_snap.c
transform_snap_animation.c
- transform_snap_object.c
+ transform_snap_object.cc
transform_snap_sequencer.c
transform.h
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 975f4370425..76d42fae444 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -59,8 +59,6 @@
* and being able to set it to zero is handy. */
/* #define USE_NUM_NO_ZERO */
-static void drawTransformApply(const struct bContext *C, ARegion *region, void *arg);
-
static void initSnapSpatial(TransInfo *t, float r_snap[2]);
bool transdata_check_local_islands(TransInfo *t, short around)
@@ -845,10 +843,6 @@ int transformEvent(TransInfo *t, const wmEvent *event)
handled = true;
}
else if (event->type == MOUSEMOVE) {
- if (t->modifiers & (MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE)) {
- t->con.mode |= CON_SELECT;
- }
-
copy_v2_v2_int(t->mval, event->mval);
/* Use this for soft redraw. Might cause flicker in object mode */
@@ -1097,6 +1091,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
/* Confirm. */
postSelectConstraint(t);
t->modifiers &= ~(MOD_CONSTRAINT_SELECT_AXIS | MOD_CONSTRAINT_SELECT_PLANE);
+ t->redraw = TREDRAW_HARD;
}
else {
if (t->options & CTX_CAMERA) {
@@ -1108,6 +1103,7 @@ int transformEvent(TransInfo *t, const wmEvent *event)
restoreTransObjects(t);
transform_mode_init(t, NULL, TFM_TRACKBALL);
}
+ t->redraw = TREDRAW_HARD;
}
else {
t->modifiers |= (event->val == TFM_MODAL_AUTOCONSTRAINT) ?
@@ -1116,13 +1112,13 @@ int transformEvent(TransInfo *t, const wmEvent *event)
if (t->con.mode & CON_APPLY) {
stopConstraint(t);
}
- else {
- initSelectConstraint(t);
- postSelectConstraint(t);
- }
+
+ initSelectConstraint(t);
+ /* Use #TREDRAW_SOFT so that #selectConstraint is only called on the next event.
+ * This allows us to "deselect" the contraint. */
+ t->redraw = TREDRAW_SOFT;
}
}
- t->redraw |= TREDRAW_HARD;
handled = true;
}
break;
@@ -1733,8 +1729,6 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
initTransInfo(C, t, op, event);
if (t->spacetype == SPACE_VIEW3D) {
- t->draw_handle_apply = ED_region_draw_cb_activate(
- t->region->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
t->draw_handle_view = ED_region_draw_cb_activate(
t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
t->draw_handle_pixel = ED_region_draw_cb_activate(
@@ -1925,18 +1919,19 @@ void transformApply(bContext *C, TransInfo *t)
{
t->context = C;
- if ((t->redraw & TREDRAW_HARD) || (t->draw_handle_apply == NULL && (t->redraw & TREDRAW_SOFT))) {
+ if (t->redraw == TREDRAW_HARD) {
selectConstraint(t);
if (t->transform) {
t->transform(t, t->mval); /* calls recalcData() */
- viewRedrawForce(C, t);
}
- t->redraw = TREDRAW_NOTHING;
}
- else if (t->redraw & TREDRAW_SOFT) {
+
+ if (t->redraw & TREDRAW_SOFT) {
viewRedrawForce(C, t);
}
+ t->redraw = TREDRAW_NOTHING;
+
/* If auto confirm is on, break after one pass */
if (t->options & CTX_AUTOCONFIRM) {
t->state = TRANS_CONFIRM;
@@ -1945,16 +1940,6 @@ void transformApply(bContext *C, TransInfo *t)
t->context = NULL;
}
-static void drawTransformApply(const bContext *C, ARegion *UNUSED(region), void *arg)
-{
- TransInfo *t = arg;
-
- if (t->redraw & TREDRAW_SOFT) {
- t->redraw |= TREDRAW_HARD;
- transformApply((bContext *)C, t);
- }
-}
-
int transformEnd(bContext *C, TransInfo *t)
{
int exit_code = OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 713cf487ac7..37478dfc187 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -188,8 +188,8 @@ typedef enum {
/** #TransInfo.redraw */
typedef enum {
TREDRAW_NOTHING = 0,
- TREDRAW_HARD = 1,
- TREDRAW_SOFT = 2,
+ TREDRAW_SOFT = (1 << 0),
+ TREDRAW_HARD = (1 << 1) | TREDRAW_SOFT,
} eRedrawFlag;
/** #TransInfo.helpline */
@@ -663,7 +663,6 @@ typedef struct TransInfo {
int mval[2];
/** use for 3d view. */
float zfac;
- void *draw_handle_apply;
void *draw_handle_view;
void *draw_handle_pixel;
void *draw_handle_cursor;
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index 81b35e4539b..0bb00032561 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -996,19 +996,10 @@ void selectConstraint(TransInfo *t)
void postSelectConstraint(TransInfo *t)
{
- if (!(t->con.mode & CON_SELECT)) {
- return;
- }
-
- t->con.mode &= ~CON_AXIS0;
- t->con.mode &= ~CON_AXIS1;
- t->con.mode &= ~CON_AXIS2;
t->con.mode &= ~CON_SELECT;
-
- setNearestAxis(t);
-
- startConstraint(t);
- t->redraw = TREDRAW_HARD;
+ if (!(t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2))) {
+ t->con.mode &= ~CON_APPLY;
+ }
}
static void setNearestAxis2d(TransInfo *t)
diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c
index 763af1f3384..1f58ec80f02 100644
--- a/source/blender/editors/transform/transform_convert_object_texspace.c
+++ b/source/blender/editors/transform/transform_convert_object_texspace.c
@@ -63,7 +63,6 @@ void createTransTexspace(TransInfo *t)
}
td->flag = TD_SELECTED;
- copy_v3_v3(td->center, ob->obmat[3]);
td->ob = ob;
copy_m3_m4(td->mtx, ob->obmat);
@@ -77,6 +76,7 @@ void createTransTexspace(TransInfo *t)
}
copy_v3_v3(td->iloc, td->loc);
+ copy_v3_v3(td->center, td->loc);
copy_v3_v3(td->ext->isize, td->ext->size);
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 3b9e2a982dc..975dbc2e986 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -718,9 +718,6 @@ void postTrans(bContext *C, TransInfo *t)
if (t->draw_handle_view) {
ED_region_draw_cb_exit(t->region->type, t->draw_handle_view);
}
- if (t->draw_handle_apply) {
- ED_region_draw_cb_exit(t->region->type, t->draw_handle_apply);
- }
if (t->draw_handle_pixel) {
ED_region_draw_cb_exit(t->region->type, t->draw_handle_pixel);
}
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 955916ff437..aa8dad2b95f 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -939,7 +939,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob_iter = objects[ob_index];
- const bool use_mat_local = params->use_local_axis && (ob_iter != ob);
+ const bool use_mat_local = (ob_iter != ob);
/* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */
const int mode = TFM_ROTATION;
@@ -951,7 +951,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
}
/* Use channels to get stats. */
- LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
+ LISTBASE_FOREACH (bPoseChannel *, pchan, &ob_iter->pose->chanbase) {
if (!(pchan->bone->flag & BONE_TRANSFORM)) {
continue;
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 7ace6343985..23619a2049a 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -567,10 +567,10 @@ static char snap_flag_from_spacetype(TransInfo *t)
if (t->spacetype == SPACE_NODE) {
return ts->snap_flag_node;
}
- else if (t->spacetype == SPACE_IMAGE) {
+ if (t->spacetype == SPACE_IMAGE) {
return ts->snap_uv_flag;
}
- else if (t->spacetype == SPACE_SEQ) {
+ if (t->spacetype == SPACE_SEQ) {
return ts->snap_flag_seq;
}
return ts->snap_flag;
@@ -579,89 +579,97 @@ static char snap_flag_from_spacetype(TransInfo *t)
static short snap_mode_from_spacetype(TransInfo *t)
{
ToolSettings *ts = t->settings;
- short r_snap_mode = SCE_SNAP_MODE_INCREMENT;
if (t->spacetype == SPACE_NODE) {
- r_snap_mode = ts->snap_node_mode;
+ return ts->snap_node_mode;
}
- else if (t->spacetype == SPACE_IMAGE) {
- r_snap_mode = ts->snap_uv_mode;
- if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) &&
+
+ if (t->spacetype == SPACE_IMAGE) {
+ short snap_mode = ts->snap_uv_mode;
+ if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_uv_flag & SCE_SNAP_ABS_GRID) &&
(t->mode == TFM_TRANSLATION)) {
- r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
- r_snap_mode |= SCE_SNAP_MODE_GRID;
+ snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
+ snap_mode |= SCE_SNAP_MODE_GRID;
}
+ return snap_mode;
}
- else if (t->spacetype == SPACE_SEQ) {
- r_snap_mode = SEQ_tool_settings_snap_mode_get(t->scene);
+
+ if (t->spacetype == SPACE_SEQ) {
+ return SEQ_tool_settings_snap_mode_get(t->scene);
}
- else if ((t->spacetype == SPACE_VIEW3D) && !(t->options & CTX_CAMERA)) {
- /* All obedit types will match. */
- const int obedit_type = t->obedit_type;
- if ((t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) ||
- ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL, -1)) {
- r_snap_mode = ts->snap_mode;
- if ((r_snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
- (t->mode == TFM_TRANSLATION)) {
- /* Special case in which snap to increments is transformed to snap to grid. */
- r_snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
- r_snap_mode |= SCE_SNAP_MODE_GRID;
- }
+
+ if (t->spacetype == SPACE_VIEW3D) {
+ if (t->options & (CTX_CAMERA | CTX_EDGE_DATA | CTX_PAINT_CURVE)) {
+ return SCE_SNAP_MODE_INCREMENT;
}
+
+ short snap_mode = ts->snap_mode;
+ if ((snap_mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) &&
+ (t->mode == TFM_TRANSLATION)) {
+ /* Special case in which snap to increments is transformed to snap to grid. */
+ snap_mode &= ~SCE_SNAP_MODE_INCREMENT;
+ snap_mode |= SCE_SNAP_MODE_GRID;
+ }
+ return snap_mode;
}
- else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
+
+ if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA)) {
/* No incremental snapping. */
- r_snap_mode = 0;
+ return 0;
}
- return r_snap_mode;
+ return SCE_SNAP_MODE_INCREMENT;
}
static short snap_select_type_get(TransInfo *t)
{
- short r_snap_select = SNAP_ALL;
-
ViewLayer *view_layer = t->view_layer;
Base *base_act = view_layer->basact;
if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) {
- const int obedit_type = t->obedit_type;
if (t->options & (CTX_GPENCIL_STROKES | CTX_CURSOR | CTX_OBMODE_XFORM_OBDATA)) {
/* In "Edit Strokes" mode,
* snap tool can perform snap to selected or active objects (see T49632)
* TODO: perform self snap in gpencil_strokes.
*
* When we're moving the origins, allow snapping onto our own geometry (see T69132). */
+ return SNAP_ALL;
}
- else if ((obedit_type != -1) &&
- ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) {
+
+ const int obedit_type = t->obedit_type;
+ if (obedit_type != -1) {
/* Edit mode */
- /* Temporary limited to edit mode meshes, armature, curves, metaballs. */
+ if (ELEM(obedit_type, OB_MESH, OB_ARMATURE, OB_CURVES_LEGACY, OB_LATTICE, OB_MBALL)) {
+ /* Temporary limited to edit mode meshes, armature, curves, lattice and metaballs. */
- if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) {
- /* Exclude editmesh if using proportional edit */
- r_snap_select = SNAP_NOT_ACTIVE;
- }
- else if (!t->tsnap.snap_self) {
- r_snap_select = SNAP_NOT_ACTIVE;
- }
- else {
- r_snap_select = SNAP_NOT_SELECTED;
+ if ((obedit_type == OB_MESH) && (t->flag & T_PROP_EDIT)) {
+ /* Exclude editmesh if using proportional edit */
+ return SNAP_NOT_EDITED;
+ }
+
+ if (!t->tsnap.snap_self) {
+ return SNAP_NOT_ACTIVE;
+ }
+
+ return SNAP_NOT_SELECTED;
}
+
+ return SNAP_ALL;
}
- else if ((obedit_type == -1) && base_act && base_act->object &&
- (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
+
+ if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) {
/* Particles edit mode. */
+ return SNAP_ALL;
}
- else if (obedit_type == -1) {
- /* Object or pose mode. */
- r_snap_select = SNAP_NOT_SELECTED;
- }
+
+ /* Object or pose mode. */
+ return SNAP_NOT_SELECTED;
}
- else if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
- r_snap_select = SNAP_NOT_SELECTED;
+
+ if (ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) {
+ return SNAP_NOT_SELECTED;
}
- return r_snap_select;
+ return SNAP_ALL;
}
static void initSnappingMode(TransInfo *t)
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.cc
index 87053fe03d1..3ef5056de85 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.cc
@@ -4,7 +4,7 @@
* \ingroup edtransform
*/
-#include <stdlib.h>
+#include <cstdlib>
#include "MEM_guardedalloc.h"
@@ -55,11 +55,12 @@ enum eViewProj {
VIEW_PROJ_PERSP = -1,
};
-typedef struct SnapObjectData {
- enum {
- SNAP_MESH = 1,
- SNAP_EDIT_MESH,
- } type;
+struct SnapObjectData {
+ enum class Type {
+ Mesh,
+ EditMesh,
+ };
+ Type type;
BVHTree *bvhtree[2]; /* MESH: loose edges, loose verts
* EDIT_MESH: verts, edges. */
@@ -67,7 +68,7 @@ typedef struct SnapObjectData {
union {
struct {
- /* SNAP_MESH */
+ /* Type::Mesh */
BVHTreeFromMesh treedata_mesh;
const struct MPoly *poly;
uint has_looptris : 1;
@@ -75,13 +76,13 @@ typedef struct SnapObjectData {
uint has_loose_vert : 1;
};
struct {
- /* SNAP_EDIT_MESH */
+ /* Type::EditMesh */
BVHTreeFromEditMesh treedata_editmesh;
float min[3], max[3];
struct Mesh_Runtime *mesh_runtime;
};
};
-} SnapObjectData;
+};
struct SnapObjectContext {
Scene *scene;
@@ -129,29 +130,29 @@ struct SnapObjectContext {
* \{ */
/* Mesh used for snapping.
- * If NULL the BMesh should be used. */
-static Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide)
+ * If nullptr the BMesh should be used. */
+static const Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, bool *r_use_hide)
{
- Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
bool use_hide = false;
if (BKE_object_is_in_editmode(ob_eval)) {
if (edit_mode_type == SNAP_GEOM_EDIT) {
- return NULL;
+ return nullptr;
}
- Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
- Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
+ const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval);
+ const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval);
if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) {
if (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
- return NULL;
+ return nullptr;
}
me_eval = editmesh_eval_final;
use_hide = true;
}
else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) {
if (editmesh_eval_cage->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) {
- return NULL;
+ return nullptr;
}
me_eval = editmesh_eval_cage;
use_hide = true;
@@ -185,24 +186,24 @@ static void bm_mesh_minmax(BMesh *bm, float r_min[3], float r_max[3])
static void snap_object_data_mesh_clear(SnapObjectData *sod)
{
- BLI_assert(sod->type == SNAP_MESH);
+ BLI_assert(sod->type == SnapObjectData::Type::Mesh);
for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
if (!sod->cached[i]) {
BLI_bvhtree_free(sod->bvhtree[i]);
}
- sod->bvhtree[i] = NULL;
+ sod->bvhtree[i] = nullptr;
}
free_bvhtree_from_mesh(&sod->treedata_mesh);
}
static void snap_object_data_editmesh_clear(SnapObjectData *sod)
{
- BLI_assert(sod->type == SNAP_EDIT_MESH);
+ BLI_assert(sod->type == SnapObjectData::Type::EditMesh);
for (int i = 0; i < ARRAY_SIZE(sod->bvhtree); i++) {
if (!sod->cached[i]) {
BLI_bvhtree_free(sod->bvhtree[i]);
}
- sod->bvhtree[i] = NULL;
+ sod->bvhtree[i] = nullptr;
}
free_bvhtree_from_editmesh(&sod->treedata_editmesh);
}
@@ -210,11 +211,11 @@ static void snap_object_data_editmesh_clear(SnapObjectData *sod)
static void snap_object_data_clear(SnapObjectData *sod)
{
switch (sod->type) {
- case SNAP_MESH: {
+ case SnapObjectData::Type::Mesh: {
snap_object_data_mesh_clear(sod);
break;
}
- case SNAP_EDIT_MESH: {
+ case SnapObjectData::Type::EditMesh: {
snap_object_data_editmesh_clear(sod);
break;
}
@@ -224,13 +225,15 @@ static void snap_object_data_clear(SnapObjectData *sod)
static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object *ob_eval)
{
- SnapObjectData *sod = BLI_ghash_lookup(sctx->cache.object_map, ob_eval);
- if (sod == NULL) {
- if (sctx->cache.data_to_object_map != NULL) {
- ob_eval = BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->data);
+ SnapObjectData *sod = static_cast<SnapObjectData *>(
+ BLI_ghash_lookup(sctx->cache.object_map, ob_eval));
+ if (sod == nullptr) {
+ if (sctx->cache.data_to_object_map != nullptr) {
+ ob_eval = static_cast<Object *>(
+ BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->data));
/* Could be NULl when mixing edit-mode and non edit-mode objects. */
- if (ob_eval != NULL) {
- sod = BLI_ghash_lookup(sctx->cache.object_map, ob_eval);
+ if (ob_eval != nullptr) {
+ sod = static_cast<SnapObjectData *>(BLI_ghash_lookup(sctx->cache.object_map, ob_eval));
}
}
}
@@ -247,9 +250,9 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
bool init = false;
if (BLI_ghash_ensure_p(sctx->cache.object_map, ob_eval, &sod_p)) {
- sod = *sod_p;
+ sod = static_cast<SnapObjectData *>(*sod_p);
bool is_dirty = false;
- if (sod->type != SNAP_MESH) {
+ if (sod->type != SnapObjectData::Type::Mesh) {
is_dirty = true;
}
else if (sod->treedata_mesh.tree && sod->treedata_mesh.cached &&
@@ -290,21 +293,22 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
}
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod = static_cast<SnapObjectData *>(*sod_p);
init = true;
}
if (init) {
- sod->type = SNAP_MESH;
+ sod->type = SnapObjectData::Type::Mesh;
/* The BVHTree from looptris is always required. */
- BLI_assert(sod->treedata_mesh.tree == NULL);
+ BLI_assert(sod->treedata_mesh.tree == nullptr);
BKE_bvhtree_from_mesh_get(&sod->treedata_mesh,
me_eval,
use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI,
4);
- if (sod->treedata_mesh.tree == NULL) {
+ if (sod->treedata_mesh.tree == nullptr) {
sod->treedata_mesh.vert = me_eval->mvert;
sod->treedata_mesh.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
sod->treedata_mesh.loop = me_eval->mloop;
@@ -312,10 +316,10 @@ static SnapObjectData *snap_object_data_mesh_get(SnapObjectContext *sctx,
BLI_assert(sod->has_looptris == false);
}
else {
- BLI_assert(sod->treedata_mesh.vert != NULL);
- BLI_assert(sod->treedata_mesh.vert_normals != NULL);
- BLI_assert(sod->treedata_mesh.loop != NULL);
- BLI_assert(sod->treedata_mesh.looptri != NULL);
+ BLI_assert(sod->treedata_mesh.vert != nullptr);
+ BLI_assert(sod->treedata_mesh.vert_normals != nullptr);
+ BLI_assert(sod->treedata_mesh.loop != nullptr);
+ BLI_assert(sod->treedata_mesh.looptri != nullptr);
sod->has_looptris = true;
}
@@ -357,12 +361,12 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
{
/* Use object-data as the key in ghash since the editmesh
* is used to create bvhtree and is the same for each linked object. */
- if (sctx->cache.data_to_object_map == NULL) {
+ if (sctx->cache.data_to_object_map == nullptr) {
sctx->cache.data_to_object_map = BLI_ghash_ptr_new(__func__);
}
void **ob_p;
if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob_eval->data, &ob_p)) {
- ob_eval = *ob_p;
+ ob_eval = static_cast<Object *>(*ob_p);
}
else {
*ob_p = ob_eval;
@@ -370,10 +374,10 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
}
if (BLI_ghash_ensure_p(sctx->cache.object_map, ob_eval, &sod_p)) {
- sod = *sod_p;
+ sod = static_cast<SnapObjectData *>(*sod_p);
bool is_dirty = false;
/* Check if the geometry has changed. */
- if (sod->type != SNAP_EDIT_MESH) {
+ if (sod->type != SnapObjectData::Type::EditMesh) {
is_dirty = true;
}
else if (sod->treedata_editmesh.em != em) {
@@ -413,12 +417,13 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
}
}
else {
- sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod = static_cast<SnapObjectData *>(*sod_p);
init = true;
}
if (init) {
- sod->type = SNAP_EDIT_MESH;
+ sod->type = SnapObjectData::Type::EditMesh;
sod->treedata_editmesh.em = em;
sod->mesh_runtime = snap_object_data_editmesh_runtime_get(ob_eval);
bm_mesh_minmax(em->bm, sod->min, sod->max);
@@ -433,12 +438,12 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx,
/** \name Iterator
* \{ */
-typedef void (*IterSnapObjsCallback)(SnapObjectContext *sctx,
- const struct SnapObjectParams *params,
- Object *ob_eval,
- float obmat[4][4],
- bool is_object_active,
- void *data);
+using IterSnapObjsCallback = void (*)(SnapObjectContext *sctx,
+ const struct SnapObjectParams *params,
+ Object *ob_eval,
+ float obmat[4][4],
+ bool is_object_active,
+ void *data);
static bool snap_object_is_snappable(const SnapObjectContext *sctx,
const eSnapSelect snap_select,
@@ -459,7 +464,11 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx,
}
if (snap_select == SNAP_NOT_ACTIVE) {
- return base_act == base;
+ return base_act != base;
+ }
+
+ if (snap_select == SNAP_NOT_EDITED) {
+ return base->object->mode != OB_MODE_EDIT;
}
if (snap_select == SNAP_NOT_SELECTED) {
@@ -490,14 +499,8 @@ static void iter_snap_objects(SnapObjectContext *sctx,
const eSnapSelect snap_select = params->snap_select;
Base *base_act = view_layer->basact;
- if (snap_select == SNAP_ONLY_ACTIVE) {
- Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base_act->object);
- sob_callback(sctx, params, obj_eval, obj_eval->obmat, true, data);
- return;
- }
-
const bool is_in_object_mode = !base_act || base_act->object->mode == OB_MODE_OBJECT;
- for (Base *base = view_layer->object_bases.first; base != NULL; base = base->next) {
+ LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
if (!snap_object_is_snappable(sctx, snap_select, base_act, base, is_in_object_mode)) {
continue;
}
@@ -506,7 +509,7 @@ static void iter_snap_objects(SnapObjectContext *sctx,
Object *obj_eval = DEG_get_evaluated_object(sctx->runtime.depsgraph, base->object);
if (obj_eval->transflag & OB_DUPLI || BKE_object_has_geometry_set_instances(obj_eval)) {
ListBase *lb = object_duplilist(sctx->runtime.depsgraph, sctx->scene, obj_eval);
- for (DupliObject *dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
+ LISTBASE_FOREACH (DupliObject *, dupli_ob, lb) {
BLI_assert(DEG_is_evaluated_object(dupli_ob->ob));
sob_callback(sctx, params, dupli_ob->ob, dupli_ob->mat, is_object_active, data);
}
@@ -554,7 +557,7 @@ static struct SnapObjectHitDepth *hit_depth_create(const float depth,
const float obmat[4][4],
uint ob_uuid)
{
- struct SnapObjectHitDepth *hit = MEM_mallocN(sizeof(*hit), __func__);
+ struct SnapObjectHitDepth *hit = MEM_new<SnapObjectHitDepth>(__func__);
hit->depth = depth;
copy_v3_v3(hit->co, co);
@@ -570,8 +573,8 @@ static struct SnapObjectHitDepth *hit_depth_create(const float depth,
static int hit_depth_cmp(const void *arg1, const void *arg2)
{
- const struct SnapObjectHitDepth *h1 = arg1;
- const struct SnapObjectHitDepth *h2 = arg2;
+ const struct SnapObjectHitDepth *h1 = static_cast<const struct SnapObjectHitDepth *>(arg1);
+ const struct SnapObjectHitDepth *h2 = static_cast<const struct SnapObjectHitDepth *>(arg2);
int val = 0;
if (h1->depth < h2->depth) {
@@ -586,7 +589,7 @@ static int hit_depth_cmp(const void *arg1, const void *arg2)
static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
{
- struct RayCastAll_Data *data = userdata;
+ struct RayCastAll_Data *data = static_cast<struct RayCastAll_Data *>(userdata);
data->raycast_callback(data->bvhdata, index, ray, hit);
if (hit->index != -1) {
/* Get all values in world-space. */
@@ -719,7 +722,7 @@ static bool raycastMesh(SnapObjectContext *sctx,
if (bb) {
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL)) {
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, nullptr)) {
return retval;
}
}
@@ -739,14 +742,14 @@ static bool raycastMesh(SnapObjectContext *sctx,
BVHTreeFromMesh *treedata = &sod->treedata_mesh;
- if (treedata->tree == NULL) {
+ if (treedata->tree == nullptr) {
return retval;
}
float timat[3][3]; /* transpose inverse matrix for normals */
transpose_m3_m4(timat, imat);
- BLI_assert(treedata->raycast_callback != NULL);
+ BLI_assert(treedata->raycast_callback != nullptr);
if (r_hit_list) {
struct RayCastAll_Data data;
@@ -772,10 +775,9 @@ static bool raycastMesh(SnapObjectContext *sctx,
retval = data.retval;
}
else {
- BVHTreeRayHit hit = {
- .index = -1,
- .dist = local_depth,
- };
+ BVHTreeRayHit hit{};
+ hit.index = -1;
+ hit.dist = local_depth;
if (BLI_bvhtree_ray_cast(treedata->tree,
ray_start_local,
@@ -859,7 +861,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, sod->min, sod->max, &len_diff, NULL)) {
+ ray_start_local, ray_normal_local, sod->min, sod->max, &len_diff, nullptr)) {
return retval;
}
@@ -877,7 +879,7 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
BVHTreeFromEditMesh *treedata = &sod->treedata_editmesh;
- if (treedata->tree == NULL) {
+ if (treedata->tree == nullptr) {
/* Operators only update the editmesh looptris of the original mesh. */
BLI_assert(sod->treedata_editmesh.em ==
BKE_editmesh_from_object(DEG_get_original_object(ob_eval)));
@@ -894,8 +896,16 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
sctx->callbacks.edit_mesh.test_face_fn,
sctx->callbacks.edit_mesh.user_data);
- bvhtree_from_editmesh_looptri_ex(
- treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, 0, NULL, NULL);
+ bvhtree_from_editmesh_looptri_ex(treedata,
+ em,
+ elem_mask,
+ looptri_num_active,
+ 0.0f,
+ 4,
+ 6,
+ BVHTREE_FROM_EM_LOOPTRI,
+ nullptr,
+ nullptr);
MEM_freeN(elem_mask);
}
@@ -907,10 +917,10 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
4,
BVHTREE_FROM_EM_LOOPTRI,
&sod->mesh_runtime->bvh_cache,
- sod->mesh_runtime->eval_mutex);
+ static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex));
}
- if (treedata->tree == NULL) {
+ if (treedata->tree == nullptr) {
return retval;
}
}
@@ -943,10 +953,9 @@ static bool raycastEditMesh(SnapObjectContext *sctx,
retval = data.retval;
}
else {
- BVHTreeRayHit hit = {
- .index = -1,
- .dist = local_depth,
- };
+ BVHTreeRayHit hit{};
+ hit.index = -1;
+ hit.dist = local_depth;
if (BLI_bvhtree_ray_cast(treedata->tree,
ray_start_local,
@@ -1013,7 +1022,7 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
bool is_object_active,
void *data)
{
- struct RaycastObjUserData *dt = data;
+ RaycastObjUserData *dt = static_cast<RaycastObjUserData *>(data);
const uint ob_index = dt->ob_index++;
bool use_occlusion_test = dt->use_occlusion_test;
/* read/write args */
@@ -1032,8 +1041,8 @@ static void raycast_obj_fn(SnapObjectContext *sctx,
case OB_MESH: {
const eSnapEditType edit_mode_type = params->edit_mode_type;
bool use_hide = false;
- Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
- if (me_eval == NULL) {
+ const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
+ if (me_eval == nullptr) {
/* Operators only update the editmesh looptris of the original mesh. */
BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob_eval));
retval = raycastEditMesh(sctx,
@@ -1154,20 +1163,19 @@ static bool raycastObjects(SnapObjectContext *sctx,
}
}
- struct RaycastObjUserData data = {
- .ray_start = ray_start,
- .ray_dir = ray_dir,
- .ob_index = 0,
- .ray_depth = ray_depth,
- .r_loc = r_loc,
- .r_no = r_no,
- .r_index = r_index,
- .r_ob = r_ob,
- .r_obmat = r_obmat,
- .r_hit_list = r_hit_list,
- .use_occlusion_test = params->use_occlusion_test,
- .ret = false,
- };
+ RaycastObjUserData data = {};
+ data.ray_start = ray_start;
+ data.ray_dir = ray_dir;
+ data.ob_index = 0;
+ data.ray_depth = ray_depth;
+ data.r_loc = r_loc;
+ data.r_no = r_no;
+ data.r_index = r_index;
+ data.r_ob = r_ob;
+ data.r_obmat = r_obmat;
+ data.r_hit_list = r_hit_list;
+ data.use_occlusion_test = params->use_occlusion_test;
+ data.ret = false;
iter_snap_objects(sctx, params, raycast_obj_fn, &data);
@@ -1211,24 +1219,24 @@ static bool snap_bound_box_check_dist(const float min[3],
struct Nearest2dUserData;
-typedef void (*Nearest2DGetVertCoCallback)(const int index,
- const struct Nearest2dUserData *data,
- const float **r_co);
-typedef void (*Nearest2DGetEdgeVertsCallback)(const int index,
+using Nearest2DGetVertCoCallback = void (*)(const int index,
+ const struct Nearest2dUserData *data,
+ const float **r_co);
+using Nearest2DGetEdgeVertsCallback = void (*)(const int index,
+ const struct Nearest2dUserData *data,
+ int r_v_index[2]);
+using Nearest2DGetTriVertsCallback = void (*)(const int index,
const struct Nearest2dUserData *data,
- int r_v_index[2]);
-typedef void (*Nearest2DGetTriVertsCallback)(const int index,
- const struct Nearest2dUserData *data,
- int r_v_index[3]);
+ int r_v_index[3]);
/* Equal the previous one */
-typedef void (*Nearest2DGetTriEdgesCallback)(const int index,
+using Nearest2DGetTriEdgesCallback = void (*)(const int index,
+ const struct Nearest2dUserData *data,
+ int r_e_index[3]);
+using Nearest2DCopyVertNoCallback = void (*)(const int index,
const struct Nearest2dUserData *data,
- int r_e_index[3]);
-typedef void (*Nearest2DCopyVertNoCallback)(const int index,
- const struct Nearest2dUserData *data,
- float r_no[3]);
+ float r_no[3]);
-typedef struct Nearest2dUserData {
+struct Nearest2dUserData {
Nearest2DGetVertCoCallback get_vert_co;
Nearest2DGetEdgeVertsCallback get_edge_verts_index;
Nearest2DGetTriVertsCallback get_tri_verts_index;
@@ -1250,7 +1258,7 @@ typedef struct Nearest2dUserData {
bool is_persp;
bool use_backface_culling;
-} Nearest2dUserData;
+};
static void cb_mvert_co_get(const int index, const Nearest2dUserData *data, const float **r_co)
{
@@ -1386,7 +1394,7 @@ static void cb_snap_vert(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
- Nearest2dUserData *data = userdata;
+ Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
const float *co;
data->get_vert_co(index, data, &co);
@@ -1410,7 +1418,7 @@ static void cb_snap_edge(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
- struct Nearest2dUserData *data = userdata;
+ Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
int vindex[2];
data->get_edge_verts_index(index, data, vindex);
@@ -1439,7 +1447,7 @@ static void cb_snap_edge_verts(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
- struct Nearest2dUserData *data = userdata;
+ Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
int vindex[2];
data->get_edge_verts_index(index, data, vindex);
@@ -1459,7 +1467,7 @@ static void cb_snap_tri_edges(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
- Nearest2dUserData *data = userdata;
+ Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
if (data->use_backface_culling) {
int vindex[3];
@@ -1494,7 +1502,7 @@ static void cb_snap_tri_verts(void *userdata,
const int clip_plane_len,
BVHTreeNearest *nearest)
{
- struct Nearest2dUserData *data = userdata;
+ Nearest2dUserData *data = static_cast<Nearest2dUserData *>(userdata);
int vindex[3];
data->get_tri_verts_index(index, data, vindex);
@@ -1523,7 +1531,7 @@ static void nearest2d_data_init(SnapObjectData *sod,
bool use_backface_culling,
Nearest2dUserData *r_nearest2d)
{
- if (sod->type == SNAP_MESH) {
+ if (sod->type == SnapObjectData::Type::Mesh) {
r_nearest2d->get_vert_co = cb_mvert_co_get;
r_nearest2d->get_edge_verts_index = cb_medge_verts_get;
r_nearest2d->copy_vert_no = cb_mvert_no_copy;
@@ -1537,12 +1545,12 @@ static void nearest2d_data_init(SnapObjectData *sod,
r_nearest2d->looptri = sod->treedata_mesh.looptri;
}
else {
- BLI_assert(sod->type == SNAP_EDIT_MESH);
+ BLI_assert(sod->type == SnapObjectData::Type::EditMesh);
r_nearest2d->get_vert_co = cb_bvert_co_get;
r_nearest2d->get_edge_verts_index = cb_bedge_verts_get;
r_nearest2d->copy_vert_no = cb_bvert_no_copy;
- r_nearest2d->get_tri_verts_index = NULL;
- r_nearest2d->get_tri_edges_index = NULL;
+ r_nearest2d->get_tri_verts_index = nullptr;
+ r_nearest2d->get_tri_edges_index = nullptr;
r_nearest2d->bm = sod->treedata_editmesh.em->bm;
}
@@ -1583,26 +1591,25 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
mul_v4_m4v4(clip_planes_local[i], tobmat, sctx->runtime.clip_plane[i]);
}
- BVHTreeNearest nearest = {
- .index = -1,
- .dist_sq = square_f(*dist_px),
- };
+ BVHTreeNearest nearest{};
+ nearest.index = -1;
+ nearest.dist_sq = square_f(*dist_px);
SnapObjectData *sod = snap_object_data_lookup(sctx, ob_eval);
- BLI_assert(sod != NULL);
+ BLI_assert(sod != nullptr);
Nearest2dUserData nearest2d;
nearest2d_data_init(
sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
- if (sod->type == SNAP_MESH) {
+ if (sod->type == SnapObjectData::Type::Mesh) {
BVHTreeFromMesh *treedata = &sod->treedata_mesh;
const MPoly *mp = &sod->poly[*r_index];
const MLoop *ml = &treedata->loop[mp->loopstart];
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
elem = SCE_SNAP_MODE_EDGE;
- BLI_assert(treedata->edge != NULL);
+ BLI_assert(treedata->edge != nullptr);
for (int i = mp->totloop; i--; ml++) {
cb_snap_edge(&nearest2d,
ml->e,
@@ -1625,7 +1632,7 @@ static short snap_mesh_polygon(SnapObjectContext *sctx,
}
}
else {
- BLI_assert(sod->type == SNAP_EDIT_MESH);
+ BLI_assert(sod->type == SnapObjectData::Type::EditMesh);
BMEditMesh *em = sod->treedata_editmesh.em;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
@@ -1702,7 +1709,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
}
SnapObjectData *sod = snap_object_data_lookup(sctx, ob_eval);
- BLI_assert(sod != NULL);
+ BLI_assert(sod != nullptr);
Nearest2dUserData nearest2d;
nearest2d_data_init(
@@ -1724,10 +1731,9 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
&neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval);
}
- BVHTreeNearest nearest = {
- .index = -1,
- .dist_sq = square_f(original_dist_px),
- };
+ BVHTreeNearest nearest{};
+ nearest.index = -1;
+ nearest.dist_sq = square_f(original_dist_px);
float lambda;
if (!isect_ray_line_v3(neasrest_precalc.ray_origin,
@@ -1749,7 +1755,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
int v_id = lambda < 0.5f ? 0 : 1;
if (test_projected_vert_dist(&neasrest_precalc,
- NULL,
+ nullptr,
0,
nearest2d.is_persp,
v_pair[v_id],
@@ -1775,7 +1781,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
mid_v3_v3v3(vmid, v_pair[0], v_pair[1]);
if (test_projected_vert_dist(&neasrest_precalc,
- NULL,
+ nullptr,
0,
nearest2d.is_persp,
vmid,
@@ -1802,7 +1808,7 @@ static short snap_mesh_edge_verts_mixed(SnapObjectContext *sctx,
&neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval);
if (test_projected_vert_dist(&neasrest_precalc,
- NULL,
+ nullptr,
0,
nearest2d.is_persp,
v_near,
@@ -1855,8 +1861,8 @@ static short snapArmature(SnapObjectContext *sctx,
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, lpmat, sctx->runtime.win_size, sctx->runtime.mval);
- bArmature *arm = ob_eval->data;
- const bool is_editmode = arm->edbo != NULL;
+ bArmature *arm = static_cast<bArmature *>(ob_eval->data);
+ const bool is_editmode = arm->edbo != nullptr;
if (is_editmode == false) {
/* Test BoundBox */
@@ -2015,7 +2021,7 @@ static short snapCurve(SnapObjectContext *sctx,
return 0;
}
- Curve *cu = ob_eval->data;
+ Curve *cu = static_cast<Curve *>(ob_eval->data);
float dist_px_sq = square_f(*dist_px);
float lpmat[4][4];
@@ -2060,7 +2066,7 @@ static short snapCurve(SnapObjectContext *sctx,
bool is_persp = sctx->runtime.view_proj == VIEW_PROJ_PERSP;
bool skip_selected = params->snap_select == SNAP_NOT_SELECTED;
- for (Nurb *nu = (use_obedit ? cu->editnurb->nurbs.first : cu->nurb.first); nu; nu = nu->next) {
+ LISTBASE_FOREACH (Nurb *, nu, (use_obedit ? &cu->editnurb->nurbs : &cu->nurb)) {
for (int u = 0; u < nu->pntsu; u++) {
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
if (use_obedit) {
@@ -2243,7 +2249,7 @@ static short snapCamera(const SnapObjectContext *sctx,
MovieClip *clip = BKE_object_movieclip_get(scene, object, false);
MovieTracking *tracking;
- if (clip == NULL) {
+ if (clip == nullptr) {
return snap_object_center(sctx, object, obmat, dist_px, r_loc, r_no, r_index);
}
if (object->transflag & OB_DUPLI) {
@@ -2262,11 +2268,8 @@ static short snapCamera(const SnapObjectContext *sctx,
dist_squared_to_projected_aabb_precalc(
&neasrest_precalc, sctx->runtime.pmat, sctx->runtime.win_size, sctx->runtime.mval);
- MovieTrackingObject *tracking_object;
- for (tracking_object = tracking->objects.first; tracking_object;
- tracking_object = tracking_object->next) {
+ LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
- MovieTrackingTrack *track;
float reconstructed_camera_mat[4][4], reconstructed_camera_imat[4][4];
float(*vertex_obmat)[4];
@@ -2277,7 +2280,7 @@ static short snapCamera(const SnapObjectContext *sctx,
invert_m4_m4(reconstructed_camera_imat, reconstructed_camera_mat);
}
- for (track = tracksbase->first; track; track = track->next) {
+ LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
float bundle_pos[3];
if ((track->flag & TRACK_HAS_BUNDLE) == 0) {
@@ -2322,7 +2325,7 @@ static short snapCamera(const SnapObjectContext *sctx,
static short snapMesh(SnapObjectContext *sctx,
const struct SnapObjectParams *params,
Object *ob_eval,
- Mesh *me_eval,
+ const Mesh *me_eval,
const float obmat[4][4],
bool use_hide,
/* read/write args */
@@ -2358,10 +2361,10 @@ static short snapMesh(SnapObjectContext *sctx,
BVHTreeFromMesh *treedata, treedata_tmp;
treedata = &sod->treedata_mesh;
- if (sod->has_loose_edge && sod->bvhtree[0] == NULL) {
+ if (sod->has_loose_edge && sod->bvhtree[0] == nullptr) {
sod->bvhtree[0] = BKE_bvhtree_from_mesh_get(
&treedata_tmp, me_eval, BVHTREE_FROM_LOOSEEDGES, 2);
- if (sod->bvhtree[0] == NULL) {
+ if (sod->bvhtree[0] == nullptr) {
sod->has_loose_edge = false;
}
sod->cached[0] = treedata_tmp.cached;
@@ -2374,10 +2377,10 @@ static short snapMesh(SnapObjectContext *sctx,
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
- if (sod->has_loose_vert && sod->bvhtree[1] == NULL) {
+ if (sod->has_loose_vert && sod->bvhtree[1] == nullptr) {
sod->bvhtree[1] = BKE_bvhtree_from_mesh_get(
&treedata_tmp, me_eval, BVHTREE_FROM_LOOSEVERTS, 2);
- if (sod->bvhtree[1] == NULL) {
+ if (sod->bvhtree[1] == nullptr) {
sod->has_loose_vert = false;
}
sod->cached[1] = treedata_tmp.cached;
@@ -2398,10 +2401,10 @@ static short snapMesh(SnapObjectContext *sctx,
nearest2d_data_init(
sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
- BVHTreeNearest nearest = {
- .index = -1,
- .dist_sq = dist_px_sq,
- };
+ BVHTreeNearest nearest{};
+ nearest.index = -1;
+ nearest.dist_sq = dist_px_sq;
+
int last_index = nearest.index;
short elem = SCE_SNAP_MODE_VERTEX;
@@ -2551,10 +2554,11 @@ static short snapEditMesh(SnapObjectContext *sctx,
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_VERTEX) {
- BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[0]};
+ BVHTreeFromEditMesh treedata{};
+ treedata.tree = sod->bvhtree[0];
- if (treedata.tree == NULL) {
- BLI_bitmap *verts_mask = NULL;
+ if (treedata.tree == nullptr) {
+ BLI_bitmap *verts_mask = nullptr;
int verts_num_active = -1;
if (sctx->callbacks.edit_mesh.test_vert_fn) {
verts_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
@@ -2565,8 +2569,16 @@ static short snapEditMesh(SnapObjectContext *sctx,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
sctx->callbacks.edit_mesh.user_data);
- bvhtree_from_editmesh_verts_ex(
- &treedata, em, verts_mask, verts_num_active, 0.0f, 2, 6, 0, NULL, NULL);
+ bvhtree_from_editmesh_verts_ex(&treedata,
+ em,
+ verts_mask,
+ verts_num_active,
+ 0.0f,
+ 2,
+ 6,
+ BVHTREE_FROM_VERTS,
+ nullptr,
+ nullptr);
MEM_freeN(verts_mask);
}
else {
@@ -2583,10 +2595,11 @@ static short snapEditMesh(SnapObjectContext *sctx,
}
if (sctx->runtime.snap_to_flag & SCE_SNAP_MODE_EDGE) {
- BVHTreeFromEditMesh treedata = {.tree = sod->bvhtree[1]};
+ BVHTreeFromEditMesh treedata{};
+ treedata.tree = sod->bvhtree[1];
- if (treedata.tree == NULL) {
- BLI_bitmap *edges_mask = NULL;
+ if (treedata.tree == nullptr) {
+ BLI_bitmap *edges_mask = nullptr;
int edges_num_active = -1;
if (sctx->callbacks.edit_mesh.test_edge_fn) {
edges_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__);
@@ -2597,8 +2610,16 @@ static short snapEditMesh(SnapObjectContext *sctx,
(bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
sctx->callbacks.edit_mesh.user_data);
- bvhtree_from_editmesh_edges_ex(
- &treedata, em, edges_mask, edges_num_active, 0.0f, 2, 6, 0, NULL, NULL);
+ bvhtree_from_editmesh_edges_ex(&treedata,
+ em,
+ edges_mask,
+ edges_num_active,
+ 0.0f,
+ 2,
+ 6,
+ BVHTREE_FROM_VERTS,
+ nullptr,
+ nullptr);
MEM_freeN(edges_mask);
}
else {
@@ -2607,7 +2628,7 @@ static short snapEditMesh(SnapObjectContext *sctx,
2,
BVHTREE_FROM_EM_EDGES,
&sod->mesh_runtime->bvh_cache,
- sod->mesh_runtime->eval_mutex);
+ static_cast<ThreadMutex *>(sod->mesh_runtime->eval_mutex));
}
sod->bvhtree[1] = treedata.tree;
sod->cached[1] = treedata.cached;
@@ -2618,10 +2639,10 @@ static short snapEditMesh(SnapObjectContext *sctx,
nearest2d_data_init(
sod, sctx->runtime.view_proj == VIEW_PROJ_PERSP, params->use_backface_culling, &nearest2d);
- BVHTreeNearest nearest = {
- .index = -1,
- .dist_sq = dist_px_sq,
- };
+ BVHTreeNearest nearest{};
+ nearest.index = -1;
+ nearest.dist_sq = dist_px_sq;
+
short elem = SCE_SNAP_MODE_VERTEX;
float tobmat[4][4], clip_planes_local[MAX_CLIPPLANE_LEN][4];
@@ -2713,15 +2734,15 @@ static void snap_obj_fn(SnapObjectContext *sctx,
bool is_object_active,
void *data)
{
- struct SnapObjUserData *dt = data;
+ SnapObjUserData *dt = static_cast<SnapObjUserData *>(data);
short retval = 0;
switch (ob_eval->type) {
case OB_MESH: {
const eSnapEditType edit_mode_type = params->edit_mode_type;
bool use_hide;
- Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
- if (me_eval == NULL) {
+ const Mesh *me_eval = mesh_for_snap(ob_eval, edit_mode_type, &use_hide);
+ if (me_eval == nullptr) {
/* Operators only update the editmesh looptris of the original mesh. */
BMEditMesh *em_orig = BKE_editmesh_from_object(DEG_get_original_object(ob_eval));
retval = snapEditMesh(
@@ -2762,7 +2783,7 @@ static void snap_obj_fn(SnapObjectContext *sctx,
break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */
case OB_SURF:
case OB_FONT: {
- Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+ const Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (mesh_eval) {
retval |= snapMesh(sctx,
params,
@@ -2835,15 +2856,14 @@ static short snapObjectsRay(SnapObjectContext *sctx,
Object **r_ob,
float r_obmat[4][4])
{
- struct SnapObjUserData data = {
- .dist_px = dist_px,
- .r_loc = r_loc,
- .r_no = r_no,
- .r_ob = r_ob,
- .r_index = r_index,
- .r_obmat = r_obmat,
- .ret = 0,
- };
+ SnapObjUserData data = {};
+ data.dist_px = dist_px;
+ data.r_loc = r_loc;
+ data.r_no = r_no;
+ data.r_ob = r_ob;
+ data.r_index = r_index;
+ data.r_obmat = r_obmat;
+ data.ret = 0;
iter_snap_objects(sctx, params, snap_obj_fn, &data);
@@ -2858,7 +2878,7 @@ static short snapObjectsRay(SnapObjectContext *sctx,
SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int flag)
{
- SnapObjectContext *sctx = MEM_callocN(sizeof(*sctx), __func__);
+ SnapObjectContext *sctx = MEM_cnew<SnapObjectContext>(__func__);
sctx->flag = flag;
@@ -2866,7 +2886,7 @@ SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int fla
sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
/* Initialize as needed (edit-mode only). */
- sctx->cache.data_to_object_map = NULL;
+ sctx->cache.data_to_object_map = nullptr;
sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
return sctx;
@@ -2874,15 +2894,15 @@ SnapObjectContext *ED_transform_snap_object_context_create(Scene *scene, int fla
static void snap_object_data_free(void *sod_v)
{
- SnapObjectData *sod = sod_v;
+ SnapObjectData *sod = static_cast<SnapObjectData *>(sod_v);
snap_object_data_clear(sod);
}
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx)
{
- BLI_ghash_free(sctx->cache.object_map, NULL, snap_object_data_free);
- if (sctx->cache.data_to_object_map != NULL) {
- BLI_ghash_free(sctx->cache.data_to_object_map, NULL, NULL);
+ BLI_ghash_free(sctx->cache.object_map, nullptr, snap_object_data_free);
+ if (sctx->cache.data_to_object_map != nullptr) {
+ BLI_ghash_free(sctx->cache.data_to_object_map, nullptr, nullptr);
}
BLI_memarena_free(sctx->cache.mem_arena);
@@ -2919,8 +2939,17 @@ bool ED_transform_snap_object_project_ray_ex(SnapObjectContext *sctx,
sctx->runtime.depsgraph = depsgraph;
sctx->runtime.v3d = v3d;
- return raycastObjects(
- sctx, params, ray_start, ray_normal, ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL);
+ return raycastObjects(sctx,
+ params,
+ ray_start,
+ ray_normal,
+ ray_depth,
+ r_loc,
+ r_no,
+ r_index,
+ r_ob,
+ r_obmat,
+ nullptr);
}
bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
@@ -2944,8 +2973,17 @@ bool ED_transform_snap_object_project_ray_all(SnapObjectContext *sctx,
float ray_depth_prev = ray_depth;
#endif
- bool retval = raycastObjects(
- sctx, params, ray_start, ray_normal, &ray_depth, NULL, NULL, NULL, NULL, NULL, r_hit_list);
+ bool retval = raycastObjects(sctx,
+ params,
+ ray_start,
+ ray_normal,
+ &ray_depth,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ r_hit_list);
/* meant to be readonly for 'all' hits, ensure it is */
#ifdef DEBUG
@@ -2988,9 +3026,9 @@ static bool transform_snap_context_project_ray_impl(SnapObjectContext *sctx,
ray_depth,
r_co,
r_no,
- NULL,
- NULL,
- NULL);
+ nullptr,
+ nullptr,
+ nullptr);
return ret;
}
@@ -3006,7 +3044,7 @@ bool ED_transform_snap_object_project_ray(SnapObjectContext *sctx,
float r_no[3])
{
float ray_depth_fallback;
- if (ray_depth == NULL) {
+ if (ray_depth == nullptr) {
ray_depth_fallback = BVH_RAYCAST_DIST_MAX;
ray_depth = &ray_depth_fallback;
}
@@ -3043,7 +3081,7 @@ static short transform_snap_context_project_view3d_mixed_impl(
short retval = 0;
bool has_hit = false;
- Object *ob_eval = NULL;
+ Object *ob_eval = nullptr;
float loc[3];
/* Not all snapping callbacks set the normal,
* initialize this since any hit copies both the `loc` and `no`. */
@@ -3051,14 +3089,14 @@ static short transform_snap_context_project_view3d_mixed_impl(
float obmat[4][4];
int index = -1;
- const RegionView3D *rv3d = region->regiondata;
+ const RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
bool use_occlusion_test = params->use_occlusion_test && !XRAY_ENABLED(v3d);
if (snap_to_flag & SCE_SNAP_MODE_FACE || use_occlusion_test) {
float ray_start[3], ray_normal[3];
if (!ED_view3d_win_to_ray_clipped_ex(
- depsgraph, region, v3d, mval, NULL, ray_normal, ray_start, true)) {
+ depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) {
return 0;
}
@@ -3074,7 +3112,7 @@ static short transform_snap_context_project_view3d_mixed_impl(
&index,
&ob_eval,
obmat,
- NULL);
+ nullptr);
if (has_hit) {
if (r_face_nor) {
@@ -3119,10 +3157,10 @@ static short transform_snap_context_project_view3d_mixed_impl(
}
planes_from_projmat(sctx->runtime.pmat,
- NULL,
- NULL,
- NULL,
- NULL,
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
sctx->runtime.clip_plane[0],
sctx->runtime.clip_plane[1]);
@@ -3255,10 +3293,10 @@ short ED_transform_snap_object_project_view3d(SnapObjectContext *sctx,
dist_px,
r_loc,
r_no,
- NULL,
- NULL,
- NULL,
- NULL);
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr);
}
bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx,
@@ -3274,7 +3312,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(SnapObjectContext *sctx,
float ray_start[3], ray_normal[3];
if (!ED_view3d_win_to_ray_clipped_ex(
- depsgraph, region, v3d, mval, NULL, ray_normal, ray_start, true)) {
+ depsgraph, region, v3d, mval, nullptr, ray_normal, ray_start, true)) {
return false;
}
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp
index 55a33720465..02ed3f463c7 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp
@@ -569,7 +569,7 @@ bool Vec3r_ptr_from_PyObject(PyObject *obj, Vec3r &vec)
bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec)
{
- if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 2) {
+ if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 2) {
return false;
}
if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) {
@@ -582,7 +582,7 @@ bool Vec2f_ptr_from_Vector(PyObject *obj, Vec2f &vec)
bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec)
{
- if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) {
+ if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) {
return false;
}
if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) {
@@ -596,7 +596,7 @@ bool Vec3f_ptr_from_Vector(PyObject *obj, Vec3f &vec)
bool Vec3r_ptr_from_Vector(PyObject *obj, Vec3r &vec)
{
- if (!VectorObject_Check(obj) || ((VectorObject *)obj)->size != 3) {
+ if (!VectorObject_Check(obj) || ((VectorObject *)obj)->vec_num != 3) {
return false;
}
if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) {
@@ -758,7 +758,7 @@ bool Vec3r_ptr_from_PyTuple(PyObject *obj, Vec3r &vec)
bool float_array_from_PyObject(PyObject *obj, float *v, int n)
{
- if (VectorObject_Check(obj) && ((VectorObject *)obj)->size == n) {
+ if (VectorObject_Check(obj) && ((VectorObject *)obj)->vec_num == n) {
if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) {
return false;
}
diff --git a/source/blender/freestyle/intern/python/BPy_MediumType.cpp b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
index 494e01967d6..cf8e900e003 100644
--- a/source/blender/freestyle/intern/python/BPy_MediumType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_MediumType.cpp
@@ -21,7 +21,7 @@ using namespace Freestyle;
PyDoc_STRVAR(MediumType_doc,
"Class hierarchy: int > :class:`MediumType`\n"
"\n"
- "The different blending modes available to similate the interaction\n"
+ "The different blending modes available to simulate the interaction\n"
"media-medium:\n"
"\n"
"* Stroke.DRY_MEDIUM: To simulate a dry medium such as Pencil or Charcoal.\n"
diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc
index 7b514b6a49b..9f742f11ce4 100644
--- a/source/blender/functions/intern/field.cc
+++ b/source/blender/functions/intern/field.cc
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "BLI_index_mask_ops.hh"
#include "BLI_map.hh"
#include "BLI_multi_value_map.hh"
#include "BLI_set.hh"
@@ -692,29 +693,21 @@ GPointer FieldConstant::value() const
* FieldEvaluator.
*/
-static Vector<int64_t> indices_from_selection(IndexMask mask, const VArray<bool> &selection)
+static IndexMask index_mask_from_selection(const IndexMask full_mask,
+ VArray<bool> &selection,
+ ResourceScope &scope)
{
- /* If the selection is just a single value, it's best to avoid calling this
- * function when constructing an IndexMask and use an IndexRange instead. */
- BLI_assert(!selection.is_single());
-
- Vector<int64_t> indices;
if (selection.is_span()) {
Span<bool> span = selection.get_internal_span();
- for (const int64_t i : mask) {
- if (span[i]) {
- indices.append(i);
- }
- }
+ return index_mask_ops::find_indices_based_on_predicate(
+ full_mask, 4096, scope.construct<Vector<int64_t>>(), [&](const int curve_index) {
+ return span[curve_index];
+ });
}
- else {
- for (const int i : mask) {
- if (selection[i]) {
- indices.append(i);
- }
- }
- }
- return indices;
+ return index_mask_ops::find_indices_based_on_predicate(
+ full_mask, 1024, scope.construct<Vector<int64_t>>(), [&](const int curve_index) {
+ return selection[curve_index];
+ });
}
int FieldEvaluator::add_with_destination(GField field, GVMutableArray dst)
@@ -763,7 +756,7 @@ static IndexMask evaluate_selection(const Field<bool> &selection_field,
}
return IndexRange(0);
}
- return scope.add_value(indices_from_selection(full_mask, selection)).as_span();
+ return index_mask_from_selection(full_mask, selection, scope);
}
return full_mask;
}
@@ -799,8 +792,7 @@ IndexMask FieldEvaluator::get_evaluated_as_mask(const int field_index)
}
return IndexRange(0);
}
-
- return scope_.add_value(indices_from_selection(mask_, varray)).as_span();
+ return index_mask_from_selection(mask_, varray, scope_);
}
IndexMask FieldEvaluator::get_evaluated_selection_as_mask()
diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc
index 502f5f0232e..8d186edc607 100644
--- a/source/blender/geometry/intern/realize_instances.cc
+++ b/source/blender/geometry/intern/realize_instances.cc
@@ -1139,8 +1139,8 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
const Curves &curves_id = *curves_info.curves;
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- const IndexRange dst_point_range{task.start_indices.point, curves.points_size()};
- const IndexRange dst_curve_range{task.start_indices.curve, curves.curves_size()};
+ const IndexRange dst_point_range{task.start_indices.point, curves.points_num()};
+ const IndexRange dst_curve_range{task.start_indices.curve, curves.curves_num()};
copy_transformed_positions(
curves.positions(), task.transform, dst_curves.positions().slice(dst_point_range));
@@ -1194,9 +1194,9 @@ static void execute_realize_curve_task(const RealizeInstancesOptions &options,
[&](const AttributeDomain domain) {
switch (domain) {
case ATTR_DOMAIN_POINT:
- return IndexRange(task.start_indices.point, curves.points_size());
+ return IndexRange(task.start_indices.point, curves.points_num());
case ATTR_DOMAIN_CURVE:
- return IndexRange(task.start_indices.curve, curves.curves_size());
+ return IndexRange(task.start_indices.curve, curves.curves_num());
default:
BLI_assert_unreachable();
return IndexRange();
diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt
index 752d4aea61c..6108629183c 100644
--- a/source/blender/gpencil_modifiers/CMakeLists.txt
+++ b/source/blender/gpencil_modifiers/CMakeLists.txt
@@ -37,6 +37,7 @@ set(SRC
intern/MOD_gpencilbuild.c
intern/MOD_gpencilcolor.c
intern/MOD_gpencildash.c
+ intern/MOD_gpencilenvelope.c
intern/MOD_gpencilhook.c
intern/MOD_gpencillattice.c
intern/MOD_gpencillength.c
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
index ff280b9ca0d..e88d864a86e 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h
@@ -35,6 +35,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_WeightAngle;
extern GpencilModifierTypeInfo modifierType_Gpencil_Lineart;
extern GpencilModifierTypeInfo modifierType_Gpencil_Dash;
extern GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap;
+extern GpencilModifierTypeInfo modifierType_Gpencil_Envelope;
/* MOD_gpencil_util.c */
void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
index e766615101a..6cf7f6f11e5 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
@@ -56,6 +56,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
INIT_GP_TYPE(Lineart);
INIT_GP_TYPE(Dash);
INIT_GP_TYPE(Shrinkwrap);
+ INIT_GP_TYPE(Envelope);
#undef INIT_GP_TYPE
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c
index 439073752da..e57b9df03f5 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c
@@ -97,12 +97,13 @@ static bool stroke_dash(const bGPDstroke *gps,
int new_stroke_offset = 0;
int trim_start = 0;
+ int sequence_length = 0;
for (int i = 0; i < dmd->segments_len; i++) {
- if (dmd->segments[i].dash + real_gap(&dmd->segments[i]) < 1) {
- BLI_assert_unreachable();
- /* This means there's a part that doesn't have any length, can't do dot-dash. */
- return false;
- }
+ sequence_length += dmd->segments[i].dash + real_gap(&dmd->segments[i]);
+ }
+ if (sequence_length < 1) {
+ /* This means the whole segment has no length, can't do dot-dash. */
+ return false;
}
const DashGpencilModifierSegment *const first_segment = &dmd->segments[0];
@@ -147,6 +148,9 @@ static bool stroke_dash(const bGPDstroke *gps,
bGPDstroke *stroke = BKE_gpencil_stroke_new(
ds->mat_nr < 0 ? gps->mat_nr : ds->mat_nr, size, gps->thickness);
+ if (ds->flag & GP_DASH_USE_CYCLIC) {
+ stroke->flag |= GP_STROKE_CYCLIC;
+ }
for (int is = 0; is < size; is++) {
bGPDspoint *p = &gps->points[new_stroke_offset + is];
@@ -204,9 +208,10 @@ static void apply_dash_for_frame(
dmd->flag & GP_LENGTH_INVERT_PASS,
dmd->flag & GP_LENGTH_INVERT_LAYERPASS,
dmd->flag & GP_LENGTH_INVERT_MATERIAL)) {
- stroke_dash(gps, dmd, &result);
- BLI_remlink(&gpf->strokes, gps);
- BKE_gpencil_free_stroke(gps);
+ if (stroke_dash(gps, dmd, &result)) {
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
}
}
bGPDstroke *gps_dash;
@@ -232,6 +237,18 @@ static void bakeModifier(Main *UNUSED(bmain),
/* -------------------------------- */
+static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
+{
+ DashGpencilModifierData *dmd = (DashGpencilModifierData *)md;
+
+ int sequence_length = 0;
+ for (int i = 0; i < dmd->segments_len; i++) {
+ sequence_length += dmd->segments[i].dash + real_gap(&dmd->segments[i]);
+ }
+ /* This means the whole segment has no length, can't do dot-dash. */
+ return sequence_length < 1;
+}
+
/* Generic "generateStrokes" callback */
static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
{
@@ -323,6 +340,7 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(sub, &ds_ptr, "radius", 0, NULL, ICON_NONE);
uiItemR(sub, &ds_ptr, "opacity", 0, NULL, ICON_NONE);
uiItemR(sub, &ds_ptr, "material_index", 0, NULL, ICON_NONE);
+ uiItemR(sub, &ds_ptr, "use_cyclic", 0, NULL, ICON_NONE);
}
gpencil_modifier_panel_end(layout, ptr);
@@ -362,7 +380,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Dash = {
/* initData */ initData,
/* freeData */ freeData,
- /* isDisabled */ NULL,
+ /* isDisabled */ isDisabled,
/* updateDepsgraph */ NULL,
/* dependsOnTime */ NULL,
/* foreachIDLink */ foreachIDLink,
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c
new file mode 100644
index 00000000000..f8ac8d95493
--- /dev/null
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c
@@ -0,0 +1,628 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2017 Blender Foundation. */
+
+/** \file
+ * \ingroup modifiers
+ */
+
+#include <stdio.h>
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_math_geom.h"
+#include "BLI_utildefines.h"
+
+#include "BLT_translation.h"
+
+#include "DNA_defaults.h"
+#include "DNA_gpencil_modifier_types.h"
+#include "DNA_gpencil_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BKE_colortools.h"
+#include "BKE_context.h"
+#include "BKE_deform.h"
+#include "BKE_gpencil.h"
+#include "BKE_gpencil_geom.h"
+#include "BKE_gpencil_modifier.h"
+#include "BKE_lib_query.h"
+#include "BKE_modifier.h"
+#include "BKE_screen.h"
+
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "RNA_access.h"
+
+#include "MOD_gpencil_modifiertypes.h"
+#include "MOD_gpencil_ui_common.h"
+#include "MOD_gpencil_util.h"
+
+#include "MEM_guardedalloc.h"
+
+static void initData(GpencilModifierData *md)
+{
+ EnvelopeGpencilModifierData *gpmd = (EnvelopeGpencilModifierData *)md;
+
+ BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier));
+
+ MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(EnvelopeGpencilModifierData), modifier);
+}
+
+static void copyData(const GpencilModifierData *md, GpencilModifierData *target)
+{
+ BKE_gpencil_modifier_copydata_generic(md, target);
+}
+
+static float calc_min_radius_v3v3(float p1[3], float p2[3], float dir[3])
+{
+ /* Use plane-conic-intersections to choose the maximal radius.
+ * The conic is defined in 4D as f({x,y,z,t}) = x*x + y*y + z*z - t*t = 0
+ * Then a plane is defined parametrically as
+ * {p}(u, v) = {p1,0}*u + {p2,0}*(1-u) + {dir,1}*v with 0 <= u <= 1 and v >= 0
+ * Now compute the intersection point with the smallest t.
+ * To do so, compute the parameters u, v such that f(p(u, v)) = 0 and v is minimal.
+ * This can be done analytically and the solution is:
+ * u = -dot(p2,dir) / dot(p1-p2, dir) +/- sqrt((dot(p2,dir) / dot(p1-p2, dir))^2 -
+ * (2*dot(p1-p2,p2)*dot(p2,dir)-dot(p2,p2)*dot(p1-p2,dir))/(dot(p1-p2,dir)*dot(p1-p2,p1-p2)));
+ * v = ({p1}u + {p2}*(1-u))^2 / (2*(dot(p1,dir)*u + dot(p2,dir)*(1-u)));
+ */
+ float diff[3];
+ float p1_dir = dot_v3v3(p1, dir);
+ float p2_dir = dot_v3v3(p2, dir);
+ float p2_sqr = len_squared_v3(p2);
+ float diff_dir = p1_dir - p2_dir;
+ float u = 0.5f;
+ if (diff_dir != 0.0f) {
+ float p = p2_dir / diff_dir;
+ sub_v3_v3v3(diff, p1, p2);
+ float diff_sqr = len_squared_v3(diff);
+ float diff_p2 = dot_v3v3(diff, p2);
+ float q = (2 * diff_p2 * p2_dir - p2_sqr * diff_dir) / (diff_dir * diff_sqr);
+ if (p * p - q >= 0) {
+ u = -p - sqrtf(p * p - q) * copysign(1.0f, p);
+ CLAMP(u, 0.0f, 1.0f);
+ }
+ else {
+ u = 0.5f - copysign(0.5f, p);
+ }
+ }
+ else {
+ float p1_sqr = len_squared_v3(p1);
+ u = p1_sqr < p2_sqr ? 1.0f : 0.0f;
+ }
+ float p[3];
+ interp_v3_v3v3(p, p2, p1, u);
+ /* v is the determined minimal radius. In case p1 and p2 are the same, there is a
+ * simple proof for the following formula using the geometric mean theorem and Thales theorem. */
+ float v = len_squared_v3(p) / (2 * interpf(p1_dir, p2_dir, u));
+ if (v < 0 || !isfinite(v)) {
+ /* No limit to the radius from this segment. */
+ return 1e16f;
+ }
+ return v;
+}
+
+static float calc_radius_limit(
+ bGPDstroke *gps, bGPDspoint *points, float dir[3], int spread, const int i)
+{
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
+ bGPDspoint *pt = &points[i];
+
+ /* NOTE this part is the second performance critical part. Improvements are welcome. */
+ float radius_limit = 1e16f;
+ float p1[3], p2[3];
+ if (is_cyclic) {
+ if (gps->totpoints / 2 < spread) {
+ spread = gps->totpoints / 2;
+ }
+ const int start = i + gps->totpoints;
+ for (int j = -spread; j <= spread; j++) {
+ j += (j == 0);
+ const int i1 = (start + j) % gps->totpoints;
+ const int i2 = (start + j + (j > 0) - (j < 0)) % gps->totpoints;
+ sub_v3_v3v3(p1, &points[i1].x, &pt->x);
+ sub_v3_v3v3(p2, &points[i2].x, &pt->x);
+ float r = calc_min_radius_v3v3(p1, p2, dir);
+ radius_limit = min_ff(radius_limit, r);
+ }
+ }
+ else {
+ const int start = max_ii(-spread, 1 - i);
+ const int end = min_ii(spread, gps->totpoints - 2 - i);
+ for (int j = start; j <= end; j++) {
+ if (j == 0) {
+ continue;
+ }
+ const int i1 = i + j;
+ const int i2 = i + j + (j > 0) - (j < 0);
+ sub_v3_v3v3(p1, &points[i1].x, &pt->x);
+ sub_v3_v3v3(p2, &points[i2].x, &pt->x);
+ float r = calc_min_radius_v3v3(p1, p2, dir);
+ radius_limit = min_ff(radius_limit, r);
+ }
+ }
+ return radius_limit;
+}
+
+static void apply_stroke_envelope(
+ bGPDstroke *gps, int spread, const int def_nr, const bool invert_vg, const float thickness)
+{
+ const bool is_cyclic = (gps->flag & GP_STROKE_CYCLIC) != 0;
+ if (is_cyclic) {
+ const int half = gps->totpoints / 2;
+ spread = abs(((spread + half) % gps->totpoints) - half);
+ }
+ else {
+ spread = min_ii(spread, gps->totpoints - 1);
+ }
+
+ const int spread_left = (spread + 2) / 2;
+ const int spread_right = (spread + 1) / 2;
+
+ /* Copy the point data. Only need positions, but extracting them
+ * is probably just as expensive as a full copy. */
+ bGPDspoint *old_points = (bGPDspoint *)MEM_dupallocN(gps->points);
+
+ /* Deform the stroke to match the envelope shape. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
+
+ /* Verify in vertex group. */
+ float weight = get_modifier_point_weight(dvert, invert_vg, def_nr);
+ if (weight < 0.0f) {
+ continue;
+ }
+
+ int index1 = i - spread_left;
+ int index2 = i + spread_right;
+ CLAMP(index1, 0, gps->totpoints - 1);
+ CLAMP(index2, 0, gps->totpoints - 1);
+
+ bGPDspoint *point = &gps->points[i];
+ point->pressure *= interpf(thickness, 1.0f, weight);
+
+ float closest[3];
+ float closest2[3];
+ copy_v3_v3(closest2, &point->x);
+ float dist = 0.0f;
+ float dist2 = 0.0f;
+ /* Create plane from point and neighbors and intersect that with the line. */
+ float v1[3], v2[3], plane_no[3];
+ sub_v3_v3v3(
+ v1,
+ &old_points[is_cyclic ? (i - 1 + gps->totpoints) % gps->totpoints : max_ii(0, i - 1)].x,
+ &old_points[i].x);
+ sub_v3_v3v3(
+ v2,
+ &old_points[is_cyclic ? (i + 1) % gps->totpoints : min_ii(gps->totpoints - 1, i + 1)].x,
+ &old_points[i].x);
+ normalize_v3(v1);
+ normalize_v3(v2);
+ sub_v3_v3v3(plane_no, v1, v2);
+ if (normalize_v3(plane_no) == 0.0f) {
+ continue;
+ }
+ /* Now find the intersections with the plane. */
+ /* NOTE this part is the first performance critical part. Improvements are welcome. */
+ float tmp_closest[3];
+ for (int j = -spread_right; j <= spread_left; j++) {
+ const int i1 = is_cyclic ? (i + j - spread_left + gps->totpoints) % gps->totpoints :
+ max_ii(0, i + j - spread_left);
+ const int i2 = is_cyclic ? (i + j + spread_right) % gps->totpoints :
+ min_ii(gps->totpoints - 1, i + j + spread_right);
+ /*bool side = dot_v3v3(&old_points[i1].x, plane_no) < dot_v3v3(plane_no, &old_points[i2].x);
+ if (side) {
+ continue;
+ }*/
+ float lambda = line_plane_factor_v3(
+ &point->x, plane_no, &old_points[i1].x, &old_points[i2].x);
+ if (lambda <= 0.0f || lambda >= 1.0f) {
+ continue;
+ }
+ interp_v3_v3v3(tmp_closest, &old_points[i1].x, &old_points[i2].x, lambda);
+
+ float dir[3];
+ sub_v3_v3v3(dir, tmp_closest, &point->x);
+ float d = len_v3(dir);
+ /* Use a formula to find the diameter of the circle that would touch the line. */
+ float cos_angle = fabsf(dot_v3v3(plane_no, &old_points[i1].x) -
+ dot_v3v3(plane_no, &old_points[i2].x)) /
+ len_v3v3(&old_points[i1].x, &old_points[i2].x);
+ d *= 2 * cos_angle / (1 + cos_angle);
+ float to_closest[3];
+ sub_v3_v3v3(to_closest, closest, &point->x);
+ if (dist == 0.0f) {
+ dist = d;
+ copy_v3_v3(closest, tmp_closest);
+ }
+ else if (dot_v3v3(to_closest, dir) >= 0) {
+ if (d > dist) {
+ dist = d;
+ copy_v3_v3(closest, tmp_closest);
+ }
+ }
+ else {
+ if (d > dist2) {
+ dist2 = d;
+ copy_v3_v3(closest2, tmp_closest);
+ }
+ }
+ }
+ if (dist == 0.0f) {
+ copy_v3_v3(closest, &point->x);
+ }
+ if (dist2 == 0.0f) {
+ copy_v3_v3(closest2, &point->x);
+ }
+ dist = dist + dist2;
+
+ if (dist < FLT_EPSILON) {
+ continue;
+ }
+
+ float use_dist = dist;
+
+ /* Apply radius limiting to not cross existing lines. */
+ float dir[3], new_center[3];
+ interp_v3_v3v3(new_center, closest2, closest, 0.5f);
+ sub_v3_v3v3(dir, new_center, &point->x);
+ if (normalize_v3(dir) != 0.0f && (is_cyclic || (i > 0 && i < gps->totpoints - 1))) {
+ const float max_radius = calc_radius_limit(gps, old_points, dir, spread, i);
+ use_dist = min_ff(use_dist, 2 * max_radius);
+ }
+
+ float fac = use_dist * weight;
+ /* The 50 is an internal constant for the default pixel size. The result can be messed up if
+ * #bGPdata.pixfactor is not default, but I think modifiers shouldn't access that. */
+ point->pressure += fac * 50.0f * GP_DEFAULT_PIX_FACTOR;
+ interp_v3_v3v3(&point->x, &point->x, new_center, fac / len_v3v3(closest, closest2));
+ }
+
+ MEM_freeN(old_points);
+}
+
+/**
+ * Apply envelope effect to the stroke.
+ */
+static void deformStroke(GpencilModifierData *md,
+ Depsgraph *UNUSED(depsgraph),
+ Object *ob,
+ bGPDlayer *gpl,
+ bGPDframe *UNUSED(gpf),
+ bGPDstroke *gps)
+{
+ EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md;
+ if (mmd->mode != GP_ENVELOPE_DEFORM) {
+ return;
+ }
+ const int def_nr = BKE_object_defgroup_name_index(ob, mmd->vgname);
+
+ if (!is_stroke_affected_by_modifier(ob,
+ mmd->layername,
+ mmd->material,
+ mmd->pass_index,
+ mmd->layer_pass,
+ 3,
+ gpl,
+ gps,
+ mmd->flag & GP_ENVELOPE_INVERT_LAYER,
+ mmd->flag & GP_ENVELOPE_INVERT_PASS,
+ mmd->flag & GP_ENVELOPE_INVERT_LAYERPASS,
+ mmd->flag & GP_ENVELOPE_INVERT_MATERIAL)) {
+ return;
+ }
+
+ if (mmd->spread <= 0) {
+ return;
+ }
+
+ apply_stroke_envelope(
+ gps, mmd->spread, def_nr, (mmd->flag & GP_ENVELOPE_INVERT_VGROUP) != 0, mmd->thickness);
+}
+
+static void add_stroke(Object *ob,
+ bGPDstroke *gps,
+ const int point_index,
+ const int connection_index,
+ const int size,
+ const int mat_nr,
+ const float thickness,
+ const float strength,
+ ListBase *results)
+{
+ bGPdata *gpd = ob->data;
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, size, gps->thickness);
+
+ const int size1 = size == 4 ? 2 : 1;
+ const int size2 = size - size1;
+
+ memcpy(&gps_dst->points[0], &gps->points[connection_index], size1 * sizeof(bGPDspoint));
+ memcpy(&gps_dst->points[size1], &gps->points[point_index], size2 * sizeof(bGPDspoint));
+
+ for (int i = 0; i < size; i++) {
+ gps_dst->points[i].pressure *= thickness;
+ gps_dst->points[i].strength *= strength;
+ memset(&gps_dst->points[i].runtime, 0, sizeof(bGPDspoint_Runtime));
+ }
+
+ if (gps->dvert != NULL) {
+ gps_dst->dvert = MEM_malloc_arrayN(size, sizeof(MDeformVert), __func__);
+ BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], size1);
+ BKE_defvert_array_copy(&gps_dst->dvert[size1], &gps->dvert[point_index], size2);
+ }
+
+ BLI_addtail(results, gps_dst);
+
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gpd, gps_dst);
+}
+
+static void add_stroke_cyclic(Object *ob,
+ bGPDstroke *gps,
+ const int point_index,
+ const int connection_index,
+ const int mat_nr,
+ const float thickness,
+ const float strength,
+ ListBase *results)
+{
+ bGPdata *gpd = ob->data;
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, 4, gps->thickness);
+
+ int connection_index2 = (connection_index + 1) % gps->totpoints;
+ int point_index2 = (point_index + 1) % gps->totpoints;
+
+ gps_dst->points[0] = gps->points[connection_index];
+ gps_dst->points[1] = gps->points[connection_index2];
+ gps_dst->points[2] = gps->points[point_index];
+ gps_dst->points[3] = gps->points[point_index2];
+ for (int i = 0; i < 4; i++) {
+ gps_dst->points[i].pressure *= thickness;
+ gps_dst->points[i].strength *= strength;
+ memset(&gps_dst->points[i].runtime, 0, sizeof(bGPDspoint_Runtime));
+ }
+
+ if (gps->dvert != NULL) {
+ gps_dst->dvert = MEM_malloc_arrayN(4, sizeof(MDeformVert), __func__);
+ BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], 1);
+ BKE_defvert_array_copy(&gps_dst->dvert[1], &gps->dvert[connection_index2], 1);
+ BKE_defvert_array_copy(&gps_dst->dvert[2], &gps->dvert[point_index], 1);
+ BKE_defvert_array_copy(&gps_dst->dvert[3], &gps->dvert[point_index2], 1);
+ }
+
+ BLI_addtail(results, gps_dst);
+
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gpd, gps_dst);
+}
+
+static void add_stroke_simple(Object *ob,
+ bGPDstroke *gps,
+ const int point_index,
+ const int connection_index,
+ const int mat_nr,
+ const float thickness,
+ const float strength,
+ ListBase *results)
+{
+ bGPdata *gpd = ob->data;
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_new(mat_nr, 2, gps->thickness);
+
+ gps_dst->points[0] = gps->points[connection_index];
+ gps_dst->points[0].pressure *= thickness;
+ gps_dst->points[0].strength *= strength;
+ memset(&gps_dst->points[0].runtime, 0, sizeof(bGPDspoint_Runtime));
+ gps_dst->points[1] = gps->points[point_index];
+ gps_dst->points[1].pressure *= thickness;
+ gps_dst->points[1].strength *= strength;
+ memset(&gps_dst->points[1].runtime, 0, sizeof(bGPDspoint_Runtime));
+
+ if (gps->dvert != NULL) {
+ gps_dst->dvert = MEM_malloc_arrayN(2, sizeof(MDeformVert), __func__);
+ BKE_defvert_array_copy(&gps_dst->dvert[0], &gps->dvert[connection_index], 1);
+ BKE_defvert_array_copy(&gps_dst->dvert[1], &gps->dvert[point_index], 1);
+ }
+
+ BLI_addtail(results, gps_dst);
+
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gpd, gps_dst);
+}
+
+static void generate_geometry(GpencilModifierData *md, Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
+{
+ EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md;
+ ListBase duplicates = {0};
+ LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
+ if (!is_stroke_affected_by_modifier(ob,
+ mmd->layername,
+ mmd->material,
+ mmd->pass_index,
+ mmd->layer_pass,
+ 3,
+ gpl,
+ gps,
+ mmd->flag & GP_ENVELOPE_INVERT_LAYER,
+ mmd->flag & GP_ENVELOPE_INVERT_PASS,
+ mmd->flag & GP_ENVELOPE_INVERT_LAYERPASS,
+ mmd->flag & GP_ENVELOPE_INVERT_MATERIAL)) {
+ continue;
+ }
+
+ const int mat_nr = mmd->mat_nr < 0 ? gps->mat_nr : min_ii(mmd->mat_nr, ob->totcol - 1);
+ if (mmd->mode == GP_ENVELOPE_FILLS) {
+ if (gps->flag & GP_STROKE_CYCLIC) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ const int connection_index = (i + mmd->spread) % gps->totpoints;
+ add_stroke_cyclic(
+ ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates);
+ }
+ }
+ else {
+ for (int i = 1; i < gps->totpoints - 1 && i < mmd->spread + 1; i++) {
+ add_stroke(ob, gps, i, 0, 3, mat_nr, mmd->thickness, mmd->strength, &duplicates);
+ }
+ for (int i = 0; i < gps->totpoints - 1; i++) {
+ const int connection_index = min_ii(i + mmd->spread, gps->totpoints - 1);
+ const int size = i == gps->totpoints - 2 ? 2 :
+ connection_index < gps->totpoints - 1 ? 4 :
+ 3;
+ add_stroke(ob,
+ gps,
+ i,
+ connection_index,
+ size,
+ mat_nr,
+ mmd->thickness,
+ mmd->strength,
+ &duplicates);
+ }
+ }
+ BLI_remlink(&gpf->strokes, gps);
+ BKE_gpencil_free_stroke(gps);
+ }
+ else {
+ BLI_assert(mmd->mode == GP_ENVELOPE_SEGMENTS);
+ if (gps->flag & GP_STROKE_CYCLIC) {
+ for (int i = 0; i < gps->totpoints; i++) {
+ const int connection_index = (i + 1 + mmd->spread) % gps->totpoints;
+ add_stroke_simple(
+ ob, gps, i, connection_index, mat_nr, mmd->thickness, mmd->strength, &duplicates);
+ }
+ }
+ else {
+ for (int i = -mmd->spread; i < gps->totpoints - 1; i++) {
+ const int connection_index = min_ii(i + 1 + mmd->spread, gps->totpoints - 1);
+ add_stroke_simple(ob,
+ gps,
+ max_ii(0, i),
+ connection_index,
+ mat_nr,
+ mmd->thickness,
+ mmd->strength,
+ &duplicates);
+ }
+ }
+ }
+ }
+ if (!BLI_listbase_is_empty(&duplicates)) {
+ /* Add strokes to the start of the stroke list to ensure the new lines are drawn underneath the
+ * original line. */
+ BLI_movelisttolist_reverse(&gpf->strokes, &duplicates);
+ }
+}
+
+/**
+ * Apply envelope effect to the strokes.
+ */
+static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Object *ob)
+{
+ EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md;
+ if (mmd->mode == GP_ENVELOPE_DEFORM || mmd->spread <= 0) {
+ return;
+ }
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ bGPdata *gpd = (bGPdata *)ob->data;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+ generate_geometry(md, ob, gpl, gpf);
+ }
+}
+
+static void bakeModifier(struct Main *UNUSED(bmain),
+ Depsgraph *depsgraph,
+ GpencilModifierData *md,
+ Object *ob)
+{
+ EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md;
+ if (mmd->mode == GP_ENVELOPE_DEFORM) {
+ generic_bake_deform_stroke(depsgraph, md, ob, false, deformStroke);
+ }
+ else {
+ bGPdata *gpd = ob->data;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ generate_geometry(md, ob, gpl, gpf);
+ }
+ }
+ }
+}
+
+static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
+{
+ EnvelopeGpencilModifierData *mmd = (EnvelopeGpencilModifierData *)md;
+
+ walk(userData, ob, (ID **)&mmd->material, IDWALK_CB_USER);
+}
+
+static void panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+
+ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "spread", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "thickness", 0, NULL, ICON_NONE);
+
+ const int mode = RNA_enum_get(ptr, "mode");
+ if (mode != GP_ENVELOPE_DEFORM) {
+ uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "mat_nr", 0, NULL, ICON_NONE);
+ }
+
+ gpencil_modifier_panel_end(layout, ptr);
+}
+
+static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel)
+{
+ gpencil_modifier_masking_panel_draw(panel, true, true);
+}
+
+static void panelRegister(ARegionType *region_type)
+{
+ PanelType *panel_type = gpencil_modifier_panel_register(
+ region_type, eGpencilModifierType_Envelope, panel_draw);
+ gpencil_modifier_subpanel_register(
+ region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type);
+}
+
+GpencilModifierTypeInfo modifierType_Gpencil_Envelope = {
+ /* name */ "Envelope",
+ /* structName */ "EnvelopeGpencilModifierData",
+ /* structSize */ sizeof(EnvelopeGpencilModifierData),
+ /* type */ eGpencilModifierTypeType_Gpencil,
+ /* flags */ eGpencilModifierTypeFlag_SupportsEditmode,
+
+ /* copyData */ copyData,
+
+ /* deformStroke */ deformStroke,
+ /* generateStrokes */ generateStrokes,
+ /* bakeModifier */ bakeModifier,
+ /* remapTime */ NULL,
+
+ /* initData */ initData,
+ /* freeData */ NULL,
+ /* isDisabled */ NULL,
+ /* updateDepsgraph */ NULL,
+ /* dependsOnTime */ NULL,
+ /* foreachIDLink */ foreachIDLink,
+ /* foreachTexLink */ NULL,
+ /* panelRegister */ panelRegister,
+};
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
index 8eaed56dc58..d80224e6639 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c
@@ -105,15 +105,15 @@ static void deformStroke(GpencilModifierData *md,
/* Apply deformed coordinates. */
pt = gps->points;
+ bGPDstroke gps_old = *gps;
+ gps_old.points = (bGPDspoint *)MEM_dupallocN(gps->points);
for (i = 0; i < gps->totpoints; i++, pt++) {
copy_v3_v3(&pt->x, vert_coords[i]);
/* Smooth stroke. */
- if (mmd->smooth_factor > 0.0f) {
- for (int r = 0; r < mmd->smooth_step; r++) {
- BKE_gpencil_stroke_smooth_point(gps, i, mmd->smooth_factor, true);
- }
- }
+ BKE_gpencil_stroke_smooth_point(
+ &gps_old, i, mmd->smooth_factor, mmd->smooth_step, true, false, gps);
}
+ MEM_freeN(gps_old.points);
MEM_freeN(vert_coords);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
index f8201eb6b4f..1992ebd1508 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
@@ -34,10 +34,14 @@
#include "UI_interface.h"
#include "UI_resources.h"
+#include "RNA_access.h"
+
#include "MOD_gpencil_modifiertypes.h"
#include "MOD_gpencil_ui_common.h"
#include "MOD_gpencil_util.h"
+#include "MEM_guardedalloc.h"
+
static void initData(GpencilModifierData *md)
{
SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md;
@@ -94,45 +98,40 @@ static void deformStroke(GpencilModifierData *md,
return;
}
- /* smooth stroke */
- if (mmd->factor > 0.0f) {
- for (int r = 0; r < mmd->step; r++) {
- for (int i = 0; i < gps->totpoints; i++) {
- MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
-
- /* verify vertex group */
- float weight = get_modifier_point_weight(
- dvert, (mmd->flag & GP_SMOOTH_INVERT_VGROUP) != 0, def_nr);
- if (weight < 0.0f) {
- continue;
- }
-
- /* Custom curve to modulate value. */
- if (use_curve) {
- float value = (float)i / (gps->totpoints - 1);
- weight *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value);
- }
-
- const float val = mmd->factor * weight;
- /* perform smoothing */
- if (mmd->flag & GP_SMOOTH_MOD_LOCATION) {
- BKE_gpencil_stroke_smooth_point(gps, i, val, false);
- }
- if (mmd->flag & GP_SMOOTH_MOD_STRENGTH) {
- BKE_gpencil_stroke_smooth_strength(gps, i, val);
- }
- if ((mmd->flag & GP_SMOOTH_MOD_THICKNESS) && (val > 0.0f)) {
- /* thickness need to repeat process several times */
- for (int r2 = 0; r2 < r * 10; r2++) {
- BKE_gpencil_stroke_smooth_thickness(gps, i, val);
- }
- }
- if (mmd->flag & GP_SMOOTH_MOD_UV) {
- BKE_gpencil_stroke_smooth_uv(gps, i, val);
- }
+ if (mmd->factor <= 0.0f || mmd->step <= 0) {
+ return;
+ }
+
+ float *weights = NULL;
+ if (def_nr != -1 || use_curve) {
+ weights = MEM_malloc_arrayN(gps->totpoints, sizeof(*weights), __func__);
+ /* Calculate weights. */
+ for (int i = 0; i < gps->totpoints; i++) {
+ MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
+
+ /* Verify vertex group. */
+ float weight = get_modifier_point_weight(
+ dvert, (mmd->flag & GP_SMOOTH_INVERT_VGROUP) != 0, def_nr);
+
+ /* Custom curve to modulate value. */
+ if (use_curve && weight > 0.0f) {
+ float value = (float)i / (gps->totpoints - 1);
+ weight *= BKE_curvemapping_evaluateF(mmd->curve_intensity, 0, value);
}
+
+ weights[i] = weight;
}
}
+ BKE_gpencil_stroke_smooth(gps,
+ mmd->factor,
+ mmd->step,
+ mmd->flag & GP_SMOOTH_MOD_LOCATION,
+ mmd->flag & GP_SMOOTH_MOD_STRENGTH,
+ mmd->flag & GP_SMOOTH_MOD_THICKNESS,
+ mmd->flag & GP_SMOOTH_MOD_UV,
+ mmd->flag & GP_SMOOTH_KEEP_SHAPE,
+ weights);
+ MEM_SAFE_FREE(weights);
}
static void bakeModifier(struct Main *UNUSED(bmain),
@@ -161,7 +160,7 @@ static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk,
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
{
- uiLayout *row;
+ uiLayout *row, *col;
uiLayout *layout = panel->layout;
PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL);
@@ -177,6 +176,10 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
uiItemR(layout, ptr, "factor", 0, NULL, ICON_NONE);
uiItemR(layout, ptr, "step", 0, IFACE_("Repeat"), ICON_NONE);
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_edit_position"));
+ uiItemR(col, ptr, "use_keep_shape", 0, NULL, ICON_NONE);
+
gpencil_modifier_panel_end(layout, ptr);
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 190454c8dfe..7b20a18890a 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -12,8 +12,8 @@ endif()
set(INC
.
intern
- opengl
metal
+ opengl
../blenkernel
../blenlib
../bmesh
@@ -104,12 +104,12 @@ set(SRC
GPU_shader.h
GPU_shader_shared.h
GPU_state.h
+ GPU_storage_buffer.h
GPU_texture.h
GPU_uniform_buffer.h
GPU_vertex_buffer.h
GPU_vertex_format.h
GPU_viewport.h
- GPU_storage_buffer.h
intern/gpu_backend.hh
intern/gpu_batch_private.hh
@@ -426,9 +426,9 @@ set(SRC_SHADER_CREATE_INFOS
../draw/engines/workbench/shaders/infos/workbench_volume_info.hh
../draw/engines/image/shaders/infos/engine_image_info.hh
../draw/intern/shaders/draw_fullscreen_info.hh
+ ../draw/intern/shaders/draw_hair_refine_info.hh
../draw/intern/shaders/draw_object_infos_info.hh
../draw/intern/shaders/draw_view_info.hh
- ../draw/intern/shaders/draw_hair_refine_info.hh
shaders/infos/gpu_clip_planes_info.hh
shaders/infos/gpu_shader_2D_area_borders_info.hh
@@ -503,16 +503,33 @@ endif()
if(WITH_GPU_SHADER_BUILDER)
- add_executable(shader_builder
- intern/gpu_shader_builder.cc
- intern/gpu_shader_builder_stubs.cc
- ${shader_create_info_list_file}
- )
+ # TODO(@fclem) Fix this mess.
+ if(APPLE)
+ add_executable(shader_builder
+ intern/gpu_shader_builder.cc
+ ${shader_create_info_list_file}
+ )
+ else()
+ add_executable(shader_builder
+ intern/gpu_shader_builder.cc
+ intern/gpu_shader_builder_stubs.cc
+ ${shader_create_info_list_file}
+ )
+ endif()
+
+ setup_platform_linker_flags(shader_builder)
+
+ if(APPLE)
+ target_link_libraries(shader_builder PUBLIC
+ bf_blenkernel
+ buildinfoobj
+ )
+ else()
+ target_link_libraries(shader_builder PUBLIC
+ bf_blenkernel
+ )
+ endif()
- target_link_libraries(shader_builder PUBLIC
- bf_blenkernel
- ${PLATFORM_LINKLIBS}
- )
target_include_directories(shader_builder PRIVATE ${INC} ${CMAKE_CURRENT_BINARY_DIR})
set(SRC_BAKED_CREATE_INFOS_FILE ${CMAKE_CURRENT_BINARY_DIR}/shader_baked.hh)
diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc
index aef1984687d..0d26f17ede5 100644
--- a/source/blender/gpu/intern/gpu_shader_create_info.cc
+++ b/source/blender/gpu/intern/gpu_shader_create_info.cc
@@ -264,9 +264,14 @@ bool gpu_shader_create_info_compile_all()
{
using namespace blender::gpu;
int success = 0;
+ int skipped = 0;
int total = 0;
for (ShaderCreateInfo *info : g_create_infos->values()) {
if (info->do_static_compilation_) {
+ if (GPU_compute_shader_support() == false && info->compute_source_ != nullptr) {
+ skipped++;
+ continue;
+ }
total++;
GPUShader *shader = GPU_shader_create_from_info(
reinterpret_cast<const GPUShaderCreateInfo *>(info));
@@ -322,12 +327,11 @@ bool gpu_shader_create_info_compile_all()
GPU_shader_free(shader);
}
}
- printf("===============================\n");
- printf("Shader Test compilation result: \n");
- printf("%d Total\n", total);
- printf("%d Passed\n", success);
- printf("%d Failed\n", total - success);
- printf("===============================\n");
+ printf("Shader Test compilation result: %d / %d passed", success, total);
+ if (skipped > 0) {
+ printf(" (skipped %d for compatibility reasons)", skipped);
+ }
+ printf("\n");
return success == total;
}
diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc
index 5a55a2e8020..71428633d79 100644
--- a/source/blender/gpu/opengl/gl_shader.cc
+++ b/source/blender/gpu/opengl/gl_shader.cc
@@ -868,7 +868,7 @@ GLuint GLShader::create_shader_stage(GLenum gl_stage, MutableSpan<const char *>
{
GLuint shader = glCreateShader(gl_stage);
if (shader == 0) {
- fprintf(stderr, "GLShader: Error: Could not create shader object.");
+ fprintf(stderr, "GLShader: Error: Could not create shader object.\n");
return 0;
}
diff --git a/source/blender/gpu/opengl/gl_shader_log.cc b/source/blender/gpu/opengl/gl_shader_log.cc
index 1d922916e4c..64567174d17 100644
--- a/source/blender/gpu/opengl/gl_shader_log.cc
+++ b/source/blender/gpu/opengl/gl_shader_log.cc
@@ -39,7 +39,8 @@ char *GLLogParser::parse_line(char *log_line, GPULogItem &log_item)
if ((log_item.cursor.row != -1) && (log_item.cursor.column != -1)) {
if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) ||
- GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) {
+ GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_MAC, GPU_DRIVER_OFFICIAL) ||
+ GPU_type_matches(GPU_DEVICE_APPLE, GPU_OS_MAC, GPU_DRIVER_OFFICIAL)) {
/* 0:line */
log_item.cursor.row = log_item.cursor.column;
log_item.cursor.column = -1;
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index 25961e6e1d5..e46326467cc 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -174,6 +174,19 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ list(APPEND SRC
+ intern/webp.c
+ )
+ list(APPEND INC_SYS
+ ${WEBP_INCLUDE_DIRS}
+ )
+ list(APPEND LIB
+ ${WEBP_LIBRARIES}
+ )
+ add_definitions(-DWITH_WEBP)
+endif()
+
list(APPEND INC
../../../intern/opencolorio
)
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index 98b7cc6e87f..934163846e4 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -80,6 +80,9 @@ enum eImbFileType {
#ifdef WITH_DDS
IMB_FTYPE_DDS = 13,
#endif
+#ifdef WITH_WEBP
+ IMB_FTYPE_WEBP = 14,
+#endif
};
/* Only for readability. */
diff --git a/source/blender/imbuf/IMB_openexr.h b/source/blender/imbuf/IMB_openexr.h
index a41053b99bf..32f393fc017 100644
--- a/source/blender/imbuf/IMB_openexr.h
+++ b/source/blender/imbuf/IMB_openexr.h
@@ -44,12 +44,12 @@ void IMB_exr_add_channel(void *handle,
* Read from file.
*/
bool IMB_exr_begin_read(
- void *handle, const char *filename, int *width, int *height, bool parse_channels);
+ void *handle, const char *filepath, int *width, int *height, bool parse_channels);
/**
* Used for output files (from #RenderResult) (single and multi-layer, single and multi-view).
*/
bool IMB_exr_begin_write(void *handle,
- const char *filename,
+ const char *filepath,
int width,
int height,
int compress,
@@ -59,7 +59,7 @@ bool IMB_exr_begin_write(void *handle,
* (FSA and Save Buffers).
*/
void IMB_exrtile_begin_write(
- void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley);
+ void *handle, const char *filepath, int mipmap, int width, int height, int tilex, int tiley);
/**
* Still clumsy name handling, layers/channels can be ordered as list in list later.
diff --git a/source/blender/imbuf/intern/IMB_filetype.h b/source/blender/imbuf/intern/IMB_filetype.h
index 035c5b10c60..31f8b3a9505 100644
--- a/source/blender/imbuf/intern/IMB_filetype.h
+++ b/source/blender/imbuf/intern/IMB_filetype.h
@@ -238,3 +238,16 @@ void imb_loadtiletiff(
bool imb_savetiff(struct ImBuf *ibuf, const char *filepath, int flags);
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Format: TIFF (#IMB_FTYPE_WEBP)
+ * \{ */
+
+bool imb_is_a_webp(const unsigned char *buf, size_t size);
+struct ImBuf *imb_loadwebp(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE]);
+bool imb_savewebp(struct ImBuf *ibuf, const char *name, int flags);
+
+/** \} */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 2e8c5cc4a40..193fda01816 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2449,12 +2449,12 @@ void IMB_colormanagement_imbuf_make_display_space(
ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
bool save_as_render,
bool allocate_result,
- const ImageFormatData *imf)
+ const ImageFormatData *image_format)
{
ImBuf *colormanaged_ibuf = ibuf;
- const bool is_movie = BKE_imtype_is_movie(imf->imtype);
- const bool requires_linear_float = BKE_imtype_requires_linear_float(imf->imtype);
- const bool do_alpha_under = imf->planes != R_IMF_PLANES_RGBA;
+ const bool is_movie = BKE_imtype_is_movie(image_format->imtype);
+ const bool requires_linear_float = BKE_imtype_requires_linear_float(image_format->imtype);
+ const bool do_alpha_under = image_format->planes != R_IMF_PLANES_RGBA;
if (ibuf->rect_float && ibuf->rect &&
(ibuf->userflags & (IB_DISPLAY_BUFFER_INVALID | IB_RECT_INVALID)) != 0) {
@@ -2464,9 +2464,9 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
const bool do_colormanagement_display = save_as_render && (is_movie || !requires_linear_float);
const bool do_colormanagement_linear = save_as_render && requires_linear_float &&
- imf->linear_colorspace_settings.name[0] &&
+ image_format->linear_colorspace_settings.name[0] &&
!IMB_colormanagement_space_name_is_scene_linear(
- imf->linear_colorspace_settings.name);
+ image_format->linear_colorspace_settings.name);
if (do_colormanagement_display || do_colormanagement_linear || do_alpha_under) {
if (allocate_result) {
@@ -2529,7 +2529,8 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
* should be pretty safe since this image buffer is supposed to be used for
* saving only and ftype would be overwritten a bit later by BKE_imbuf_write
*/
- colormanaged_ibuf->ftype = BKE_imtype_to_ftype(imf->imtype, &colormanaged_ibuf->foptions);
+ colormanaged_ibuf->ftype = BKE_imtype_to_ftype(image_format->imtype,
+ &colormanaged_ibuf->foptions);
/* if file format isn't able to handle float buffer itself,
* we need to allocate byte buffer and store color managed
@@ -2543,8 +2544,10 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
}
/* perform color space conversions */
- colormanagement_imbuf_make_display_space(
- colormanaged_ibuf, &imf->view_settings, &imf->display_settings, make_byte);
+ colormanagement_imbuf_make_display_space(colormanaged_ibuf,
+ &image_format->view_settings,
+ &image_format->display_settings,
+ make_byte);
if (colormanaged_ibuf->rect_float) {
/* float buffer isn't linear anymore,
@@ -2552,7 +2555,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
* no space conversion should happen if ibuf->float_colorspace != NULL
*/
colormanaged_ibuf->float_colorspace = display_transform_get_colorspace(
- &imf->view_settings, &imf->display_settings);
+ &image_format->view_settings, &image_format->display_settings);
}
}
else if (do_colormanagement_linear) {
@@ -2565,7 +2568,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf,
if (colormanaged_ibuf->rect_float) {
const char *from_colorspace = (ibuf->float_colorspace) ? ibuf->float_colorspace->name :
global_role_scene_linear;
- const char *to_colorspace = imf->linear_colorspace_settings.name;
+ const char *to_colorspace = image_format->linear_colorspace_settings.name;
IMB_colormanagement_transform(colormanaged_ibuf->rect_float,
colormanaged_ibuf->x,
diff --git a/source/blender/imbuf/intern/filetype.c b/source/blender/imbuf/intern/filetype.c
index 60442f97885..548bc9e120c 100644
--- a/source/blender/imbuf/intern/filetype.c
+++ b/source/blender/imbuf/intern/filetype.c
@@ -197,6 +197,20 @@ const ImFileType IMB_FILE_TYPES[] = {
.default_save_role = COLOR_ROLE_DEFAULT_FLOAT,
},
#endif
+#ifdef WITH_WEBP
+ {
+ .init = NULL,
+ .exit = NULL,
+ .is_a = imb_is_a_webp,
+ .load = imb_loadwebp,
+ .load_filepath = NULL,
+ .save = imb_savewebp,
+ .load_tile = NULL,
+ .flag = 0,
+ .filetype = IMB_FTYPE_WEBP,
+ .default_save_role = COLOR_ROLE_DEFAULT_BYTE,
+ },
+#endif
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0},
};
diff --git a/source/blender/imbuf/intern/openexr/CMakeLists.txt b/source/blender/imbuf/intern/openexr/CMakeLists.txt
index 681176d8cc4..c34a97f6837 100644
--- a/source/blender/imbuf/intern/openexr/CMakeLists.txt
+++ b/source/blender/imbuf/intern/openexr/CMakeLists.txt
@@ -17,8 +17,8 @@ set(INC_SYS
)
set(SRC
- openexr_api.h
openexr_api.cpp
+ openexr_api.h
)
set(LIB
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index aff9257d1f2..9948aaac5da 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -155,15 +155,15 @@ class IMemStream : public Imf::IStream {
class IFileStream : public Imf::IStream {
public:
- IFileStream(const char *filename) : IStream(filename)
+ IFileStream(const char *filepath) : IStream(filepath)
{
/* utf-8 file path support on windows */
#if defined(WIN32)
- wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
- ifs.open(wfilename, std::ios_base::binary);
- free(wfilename);
+ wchar_t *wfilepath = alloc_utf16_from_8(filepath, 0);
+ ifs.open(wfilepath, std::ios_base::binary);
+ free(wfilepath);
#else
- ifs.open(filename, std::ios_base::binary);
+ ifs.open(filepath, std::ios_base::binary);
#endif
if (!ifs) {
@@ -261,15 +261,15 @@ class OMemStream : public OStream {
class OFileStream : public OStream {
public:
- OFileStream(const char *filename) : OStream(filename)
+ OFileStream(const char *filepath) : OStream(filepath)
{
/* utf-8 file path support on windows */
#if defined(WIN32)
- wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
- ofs.open(wfilename, std::ios_base::binary);
- free(wfilename);
+ wchar_t *wfilepath = alloc_utf16_from_8(filepath, 0);
+ ofs.open(wfilepath, std::ios_base::binary);
+ free(wfilepath);
#else
- ofs.open(filename, std::ios_base::binary);
+ ofs.open(filepath, std::ios_base::binary);
#endif
if (!ofs) {
@@ -834,7 +834,7 @@ void IMB_exr_add_channel(void *handle,
}
bool IMB_exr_begin_write(void *handle,
- const char *filename,
+ const char *filepath,
int width,
int height,
int compress,
@@ -872,7 +872,7 @@ bool IMB_exr_begin_write(void *handle,
/* avoid crash/abort when we don't have permission to write here */
/* manually create ofstream, so we can handle utf-8 filepaths on windows */
try {
- data->ofile_stream = new OFileStream(filename);
+ data->ofile_stream = new OFileStream(filepath);
data->ofile = new OutputFile(*(data->ofile_stream), header);
}
catch (const std::exception &exc) {
@@ -889,7 +889,7 @@ bool IMB_exr_begin_write(void *handle,
}
void IMB_exrtile_begin_write(
- void *handle, const char *filename, int mipmap, int width, int height, int tilex, int tiley)
+ void *handle, const char *filepath, int mipmap, int width, int height, int tilex, int tiley)
{
ExrHandle *data = (ExrHandle *)handle;
Header header(width, height);
@@ -941,7 +941,7 @@ void IMB_exrtile_begin_write(
/* avoid crash/abort when we don't have permission to write here */
/* manually create ofstream, so we can handle utf-8 filepaths on windows */
try {
- data->ofile_stream = new OFileStream(filename);
+ data->ofile_stream = new OFileStream(filepath);
data->mpofile = new MultiPartOutputFile(*(data->ofile_stream), &headers[0], headers.size());
}
catch (const std::exception &) {
@@ -954,19 +954,19 @@ void IMB_exrtile_begin_write(
}
bool IMB_exr_begin_read(
- void *handle, const char *filename, int *width, int *height, const bool parse_channels)
+ void *handle, const char *filepath, int *width, int *height, const bool parse_channels)
{
ExrHandle *data = (ExrHandle *)handle;
ExrChannel *echan;
/* 32 is arbitrary, but zero length files crashes exr. */
- if (!(BLI_exists(filename) && BLI_file_size(filename) > 32)) {
+ if (!(BLI_exists(filepath) && BLI_file_size(filepath) > 32)) {
return false;
}
/* avoid crash/abort when we don't have permission to write here */
try {
- data->ifile_stream = new IFileStream(filename);
+ data->ifile_stream = new IFileStream(filepath);
data->ifile = new MultiPartInputFile(*(data->ifile_stream));
}
catch (const std::exception &) {
diff --git a/source/blender/imbuf/intern/openexr/openexr_stub.cpp b/source/blender/imbuf/intern/openexr/openexr_stub.cpp
index 2a655360aa5..f8f204af70c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_stub.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_stub.cpp
@@ -29,7 +29,7 @@ void IMB_exr_add_channel(void * /*handle*/,
}
bool IMB_exr_begin_read(void * /*handle*/,
- const char * /*filename*/,
+ const char * /*filepath*/,
int * /*width*/,
int * /*height*/,
const bool /*add_channels*/)
@@ -37,7 +37,7 @@ bool IMB_exr_begin_read(void * /*handle*/,
return false;
}
bool IMB_exr_begin_write(void * /*handle*/,
- const char * /*filename*/,
+ const char * /*filepath*/,
int /*width*/,
int /*height*/,
int /*compress*/,
@@ -46,7 +46,7 @@ bool IMB_exr_begin_write(void * /*handle*/,
return false;
}
void IMB_exrtile_begin_write(void * /*handle*/,
- const char * /*filename*/,
+ const char * /*filepath*/,
int /*mipmap*/,
int /*width*/,
int /*height*/,
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 241f1a736f4..45b50c866fe 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -41,12 +41,12 @@
#define UTIL_DEBUG 0
const char *imb_ext_image[] = {
- ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
+ ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
#ifdef WITH_TIFF
- ".tif", ".tiff", ".tx",
+ ".tif", ".tiff", ".tx",
#endif
#ifdef WITH_OPENJPEG
- ".jp2", ".j2c",
+ ".jp2", ".j2c",
#endif
#ifdef WITH_HDR
".hdr",
@@ -55,13 +55,16 @@ const char *imb_ext_image[] = {
".dds",
#endif
#ifdef WITH_CINEON
- ".dpx", ".cin",
+ ".dpx", ".cin",
#endif
#ifdef WITH_OPENEXR
".exr",
#endif
#ifdef WITH_OPENIMAGEIO
- ".psd", ".pdd", ".psb",
+ ".psd", ".pdd", ".psb",
+#endif
+#ifdef WITH_WEBP
+ ".webp",
#endif
NULL,
};
diff --git a/source/blender/imbuf/intern/webp.c b/source/blender/imbuf/intern/webp.c
new file mode 100644
index 00000000000..19fe2373ea0
--- /dev/null
+++ b/source/blender/imbuf/intern/webp.c
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup imbuf
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <webp/decode.h>
+#include <webp/encode.h>
+
+#include "BLI_fileops.h"
+#include "BLI_utildefines.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_colormanagement_intern.h"
+#include "IMB_filetype.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "MEM_guardedalloc.h"
+
+bool imb_is_a_webp(const unsigned char *buf, size_t size)
+{
+ if (WebPGetInfo(buf, size, NULL, NULL)) {
+ return true;
+ }
+ return false;
+}
+
+ImBuf *imb_loadwebp(const unsigned char *mem,
+ size_t size,
+ int flags,
+ char colorspace[IM_MAX_SPACE])
+{
+ if (!imb_is_a_webp(mem, size)) {
+ return NULL;
+ }
+
+ colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
+
+ WebPBitstreamFeatures features;
+ if (WebPGetFeatures(mem, size, &features) != VP8_STATUS_OK) {
+ fprintf(stderr, "WebP: Failed to parse features\n");
+ return NULL;
+ }
+
+ const int planes = features.has_alpha ? 32 : 24;
+ ImBuf *ibuf = IMB_allocImBuf(features.width, features.height, planes, 0);
+
+ if (ibuf == NULL) {
+ fprintf(stderr, "WebP: Failed to allocate image memory\n");
+ return NULL;
+ }
+
+ if ((flags & IB_test) == 0) {
+ ibuf->ftype = IMB_FTYPE_WEBP;
+ imb_addrectImBuf(ibuf);
+ /* Flip the image during decoding to match Blender. */
+ unsigned char *last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
+ if (WebPDecodeRGBAInto(mem, size, last_row, (size_t)(ibuf->x) * ibuf->y * 4, -4 * ibuf->x) ==
+ NULL) {
+ fprintf(stderr, "WebP: Failed to decode image\n");
+ }
+ }
+
+ return ibuf;
+}
+
+bool imb_savewebp(struct ImBuf *ibuf, const char *name, int UNUSED(flags))
+{
+ const int bytesperpixel = (ibuf->planes + 7) >> 3;
+ unsigned char *encoded_data, *last_row;
+ size_t encoded_data_size;
+
+ if (bytesperpixel == 3) {
+ /* We must convert the ImBuf RGBA buffer to RGB as WebP expects a RGB buffer. */
+ const size_t num_pixels = ibuf->x * ibuf->y;
+ const uint8_t *rgba_rect = (uint8_t *)ibuf->rect;
+ uint8_t *rgb_rect = MEM_mallocN(sizeof(uint8_t) * num_pixels * 3, "webp rgb_rect");
+ for (int i = 0; i < num_pixels; i++) {
+ rgb_rect[i * 3 + 0] = rgba_rect[i * 4 + 0];
+ rgb_rect[i * 3 + 1] = rgba_rect[i * 4 + 1];
+ rgb_rect[i * 3 + 2] = rgba_rect[i * 4 + 2];
+ }
+
+ last_row = (unsigned char *)(rgb_rect + (ibuf->y - 1) * ibuf->x * 3);
+
+ if (ibuf->foptions.quality == 100.0f) {
+ encoded_data_size = WebPEncodeLosslessRGB(
+ last_row, ibuf->x, ibuf->y, -3 * ibuf->x, &encoded_data);
+ }
+ else {
+ encoded_data_size = WebPEncodeRGB(
+ last_row, ibuf->x, ibuf->y, -3 * ibuf->x, ibuf->foptions.quality, &encoded_data);
+ }
+ MEM_freeN(rgb_rect);
+ }
+ else if (bytesperpixel == 4) {
+ last_row = (unsigned char *)(ibuf->rect + (ibuf->y - 1) * ibuf->x);
+
+ if (ibuf->foptions.quality == 100.0f) {
+ encoded_data_size = WebPEncodeLosslessRGBA(
+ last_row, ibuf->x, ibuf->y, -4 * ibuf->x, &encoded_data);
+ }
+ else {
+ encoded_data_size = WebPEncodeRGBA(
+ last_row, ibuf->x, ibuf->y, -4 * ibuf->x, ibuf->foptions.quality, &encoded_data);
+ }
+ }
+ else {
+ fprintf(stderr, "WebP: Unsupported bytes per pixel: %d for file: '%s'\n", bytesperpixel, name);
+ return false;
+ }
+
+ if (encoded_data != NULL) {
+ FILE *fp = BLI_fopen(name, "wb");
+ if (!fp) {
+ free(encoded_data);
+ fprintf(stderr, "WebP: Cannot open file for writing: '%s'\n", name);
+ return false;
+ }
+ fwrite(encoded_data, encoded_data_size, 1, fp);
+ free(encoded_data);
+ fclose(fp);
+ }
+
+ return true;
+}
diff --git a/source/blender/io/gpencil/gpencil_io.h b/source/blender/io/gpencil/gpencil_io.h
index 6cd9fe087a6..215891e3e48 100644
--- a/source/blender/io/gpencil/gpencil_io.h
+++ b/source/blender/io/gpencil/gpencil_io.h
@@ -72,11 +72,11 @@ typedef enum eGpencilExportFrame {
/**
* Main export entry point function.
*/
-bool gpencil_io_export(const char *filename, struct GpencilIOParams *iparams);
+bool gpencil_io_export(const char *filepath, struct GpencilIOParams *iparams);
/**
* Main import entry point function.
*/
-bool gpencil_io_import(const char *filename, struct GpencilIOParams *iparams);
+bool gpencil_io_import(const char *filepath, struct GpencilIOParams *iparams);
#ifdef __cplusplus
}
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc
index 9379e72bdd9..05f1158c57d 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc
@@ -174,10 +174,10 @@ void GpencilIO::create_object_list()
});
}
-void GpencilIO::filename_set(const char *filename)
+void GpencilIO::filepath_set(const char *filepath)
{
- BLI_strncpy(filename_, filename, FILE_MAX);
- BLI_path_abs(filename_, BKE_main_blendfile_path(bmain_));
+ BLI_strncpy(filepath_, filepath, FILE_MAX);
+ BLI_path_abs(filepath_, BKE_main_blendfile_path(bmain_));
}
bool GpencilIO::gpencil_3D_point_to_screen_space(const float3 co, float2 &r_co)
diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh
index 96ba49c31b1..a89b723ed6c 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_base.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh
@@ -40,7 +40,7 @@ class GpencilIO {
bool invert_axis_[2];
float4x4 diff_mat_;
- char filename_[FILE_MAX];
+ char filepath_[FILE_MAX];
/* Used for sorting objects. */
struct ObjectZ {
@@ -94,9 +94,9 @@ class GpencilIO {
void selected_objects_boundbox_get(rctf *boundbox);
/**
* Set file input_text full path.
- * \param filename: Path of the file provided by save dialog.
+ * \param filepath: Path of the file provided by save dialog.
*/
- void filename_set(const char *filename);
+ void filepath_set(const char *filepath);
private:
float avg_opacity_;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_capi.cc b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
index 5acac885a38..84b273bc570 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_capi.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_capi.cc
@@ -161,32 +161,32 @@ static bool gpencil_io_export_frame_svg(GpencilExporterSVG *exporter,
}
#endif
-bool gpencil_io_import(const char *filename, GpencilIOParams *iparams)
+bool gpencil_io_import(const char *filepath, GpencilIOParams *iparams)
{
- GpencilImporterSVG importer = GpencilImporterSVG(filename, iparams);
+ GpencilImporterSVG importer = GpencilImporterSVG(filepath, iparams);
return gpencil_io_import_frame(&importer, *iparams);
}
-bool gpencil_io_export(const char *filename, GpencilIOParams *iparams)
+bool gpencil_io_export(const char *filepath, GpencilIOParams *iparams)
{
Depsgraph *depsgraph_ = CTX_data_depsgraph_pointer(iparams->C);
Scene *scene_ = CTX_data_scene(iparams->C);
Object *ob = CTX_data_active_object(iparams->C);
- UNUSED_VARS(filename, depsgraph_, scene_, ob);
+ UNUSED_VARS(filepath, depsgraph_, scene_, ob);
switch (iparams->mode) {
#ifdef WITH_PUGIXML
case GP_EXPORT_TO_SVG: {
- GpencilExporterSVG exporter = GpencilExporterSVG(filename, iparams);
+ GpencilExporterSVG exporter = GpencilExporterSVG(filepath, iparams);
return gpencil_io_export_frame_svg(&exporter, scene_, iparams, true, true, true);
break;
}
#endif
#ifdef WITH_HARU
case GP_EXPORT_TO_PDF: {
- GpencilExporterPDF exporter = GpencilExporterPDF(filename, iparams);
+ GpencilExporterPDF exporter = GpencilExporterPDF(filepath, iparams);
return gpencil_io_export_pdf(depsgraph_, scene_, ob, &exporter, iparams);
break;
}
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
index cc3eab02e07..205ab788e6d 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc
@@ -43,10 +43,10 @@ static void error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *UNU
}
/* Constructor. */
-GpencilExporterPDF::GpencilExporterPDF(const char *filename, const GpencilIOParams *iparams)
+GpencilExporterPDF::GpencilExporterPDF(const char *filepath, const GpencilIOParams *iparams)
: GpencilExporter(iparams)
{
- filename_set(filename);
+ filepath_set(filepath);
invert_axis_[0] = false;
invert_axis_[1] = false;
@@ -78,16 +78,16 @@ bool GpencilExporterPDF::write()
/* TODO: It looks `libharu` does not support unicode. */
#if 0 /* `ifdef WIN32` */
- char filename_cstr[FILE_MAX];
- BLI_strncpy(filename_cstr, filename_, FILE_MAX);
+ char filepath_cstr[FILE_MAX];
+ BLI_strncpy(filepath_cstr, filepath_, FILE_MAX);
- UTF16_ENCODE(filename_cstr);
- std::wstring wstr(filename_cstr_16);
+ UTF16_ENCODE(filepath_cstr);
+ std::wstring wstr(filepath_cstr_16);
res = HPDF_SaveToFile(pdf_, wstr.c_str());
- UTF16_UN_ENCODE(filename_cstr);
+ UTF16_UN_ENCODE(filepath_cstr);
#else
- res = HPDF_SaveToFile(pdf_, filename_);
+ res = HPDF_SaveToFile(pdf_, filepath_);
#endif
return (res == 0) ? true : false;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh
index f6b9fe4fec1..bfec6bc506b 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.hh
@@ -21,7 +21,7 @@ namespace blender::io::gpencil {
class GpencilExporterPDF : public GpencilExporter {
public:
- GpencilExporterPDF(const char *filename, const struct GpencilIOParams *iparams);
+ GpencilExporterPDF(const char *filepath, const struct GpencilIOParams *iparams);
bool new_document();
bool add_newpage();
bool add_body();
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
index f8d30546e39..5d33a2806bd 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc
@@ -40,10 +40,10 @@
namespace blender ::io ::gpencil {
/* Constructor. */
-GpencilExporterSVG::GpencilExporterSVG(const char *filename, const GpencilIOParams *iparams)
+GpencilExporterSVG::GpencilExporterSVG(const char *filepath, const GpencilIOParams *iparams)
: GpencilExporter(iparams)
{
- filename_set(filename);
+ filepath_set(filepath);
invert_axis_[0] = false;
invert_axis_[1] = true;
@@ -66,16 +66,16 @@ bool GpencilExporterSVG::write()
bool result = true;
/* Support unicode character paths on Windows. */
#ifdef WIN32
- char filename_cstr[FILE_MAX];
- BLI_strncpy(filename_cstr, filename_, FILE_MAX);
+ char filepath_cstr[FILE_MAX];
+ BLI_strncpy(filepath_cstr, filepath_, FILE_MAX);
- UTF16_ENCODE(filename_cstr);
- std::wstring wstr(filename_cstr_16);
+ UTF16_ENCODE(filepath_cstr);
+ std::wstring wstr(filepath_cstr_16);
result = main_doc_.save_file(wstr.c_str());
- UTF16_UN_ENCODE(filename_cstr);
+ UTF16_UN_ENCODE(filepath_cstr);
#else
- result = main_doc_.save_file(filename_);
+ result = main_doc_.save_file(filepath_);
#endif
return result;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh
index 2e1cc231e68..7bbc2710693 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.hh
@@ -20,7 +20,7 @@ namespace blender::io::gpencil {
class GpencilExporterSVG : public GpencilExporter {
public:
- GpencilExporterSVG(const char *filename, const struct GpencilIOParams *iparams);
+ GpencilExporterSVG(const char *filepath, const struct GpencilIOParams *iparams);
bool add_newpage();
bool add_body();
bool write();
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
index bad5c7d6401..06460a1beba 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc
@@ -33,17 +33,17 @@ using blender::MutableSpan;
namespace blender::io::gpencil {
/* Constructor. */
-GpencilImporterSVG::GpencilImporterSVG(const char *filename, const GpencilIOParams *iparams)
+GpencilImporterSVG::GpencilImporterSVG(const char *filepath, const GpencilIOParams *iparams)
: GpencilImporter(iparams)
{
- filename_set(filename);
+ filepath_set(filepath);
}
bool GpencilImporterSVG::read()
{
bool result = true;
NSVGimage *svg_data = nullptr;
- svg_data = nsvgParseFromFile(filename_, "mm", 96.0f);
+ svg_data = nsvgParseFromFile(filepath_, "mm", 96.0f);
if (svg_data == nullptr) {
std::cout << " Could not open SVG.\n ";
return false;
diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
index f1f4e9a6290..d868e672567 100644
--- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
+++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.hh
@@ -21,7 +21,7 @@ namespace blender::io::gpencil {
class GpencilImporterSVG : public GpencilImporter {
public:
- GpencilImporterSVG(const char *filename, const struct GpencilIOParams *iparams);
+ GpencilImporterSVG(const char *filepath, const struct GpencilIOParams *iparams);
bool read();
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 01d0cfcd302..2b5ea39617e 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -107,10 +107,10 @@ list(APPEND LIB
blender_add_lib(bf_usd "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
if(WIN32)
- set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /WHOLEARCHIVE:${USD_DEBUG_LIB}")
- set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /WHOLEARCHIVE:${USD_RELEASE_LIB}")
- set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /WHOLEARCHIVE:${USD_RELEASE_LIB}")
- set_property(TARGET bf_usd APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /WHOLEARCHIVE:${USD_RELEASE_LIB}")
+ set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:Debug>:/WHOLEARCHIVE:${USD_DEBUG_LIB}>")
+ set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:Release>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>")
+ set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:RelWithDebInfo>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>")
+ set_property(TARGET bf_usd APPEND_STRING PROPERTY INTERFACE_LINK_OPTIONS "$<$<CONFIG:MinSizeRel>:/WHOLEARCHIVE:${USD_RELEASE_LIB}>")
endif()
# Source: https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 49d5251198a..e5083700d7d 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -391,7 +391,7 @@ bool USD_import(struct bContext *C,
else {
/* Fake a job context, so that we don't need NULL pointer checks while importing. */
short stop = 0, do_update = 0;
- float progress = 0.f;
+ float progress = 0.0f;
import_startjob(job, &stop, &do_update, &progress);
import_endjob(job);
diff --git a/source/blender/io/usd/intern/usd_reader_light.cc b/source/blender/io/usd/intern/usd_reader_light.cc
index 649ff45a6d0..55b9557dfb5 100644
--- a/source/blender/io/usd/intern/usd_reader_light.cc
+++ b/source/blender/io/usd/intern/usd_reader_light.cc
@@ -9,8 +9,6 @@
#include "DNA_light_types.h"
#include "DNA_object_types.h"
-#include <pxr/usd/usdLux/light.h>
-
#include <pxr/usd/usdLux/diskLight.h>
#include <pxr/usd/usdLux/distantLight.h>
#include <pxr/usd/usdLux/rectLight.h>
@@ -40,14 +38,17 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
if (!prim_) {
return;
}
+#if PXR_VERSION >= 2111
+ pxr::UsdLuxLightAPI light_api(prim_);
+#else
+ pxr::UsdLuxLight light_api(prim_);
+#endif
- pxr::UsdLuxLight light_prim(prim_);
-
- if (!light_prim) {
+ if (!light_api) {
return;
}
- pxr::UsdLuxShapingAPI shaping_api(light_prim);
+ pxr::UsdLuxShapingAPI shaping_api;
/* Set light type. */
@@ -63,6 +64,8 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
else if (prim_.IsA<pxr::UsdLuxSphereLight>()) {
blight->type = LA_LOCAL;
+ shaping_api = pxr::UsdLuxShapingAPI(prim_);
+
if (shaping_api && shaping_api.GetShapingConeAngleAttr().IsAuthored()) {
blight->type = LA_SPOT;
}
@@ -73,7 +76,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
/* Set light values. */
- if (pxr::UsdAttribute intensity_attr = light_prim.GetIntensityAttr()) {
+ if (pxr::UsdAttribute intensity_attr = light_api.GetIntensityAttr()) {
float intensity = 0.0f;
if (intensity_attr.Get(&intensity, motionSampleTime)) {
blight->energy = intensity * this->import_params_.light_intensity_scale;
@@ -92,14 +95,14 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime
light_prim.GetDiffuseAttr().Get(&diffuse, motionSampleTime);
#endif
- if (pxr::UsdAttribute spec_attr = light_prim.GetSpecularAttr()) {
+ if (pxr::UsdAttribute spec_attr = light_api.GetSpecularAttr()) {
float spec = 0.0f;
if (spec_attr.Get(&spec, motionSampleTime)) {
blight->spec_fac = spec;
}
}
- if (pxr::UsdAttribute color_attr = light_prim.GetColorAttr()) {
+ if (pxr::UsdAttribute color_attr = light_api.GetColorAttr()) {
pxr::GfVec3f color;
if (color_attr.Get(&color, motionSampleTime)) {
blight->r = color[0];
diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc
index 06f7d3ce3f5..583c58a1356 100644
--- a/source/blender/io/usd/intern/usd_reader_stage.cc
+++ b/source/blender/io/usd/intern/usd_reader_stage.cc
@@ -18,7 +18,13 @@
#include <pxr/usd/usdGeom/nurbsCurves.h>
#include <pxr/usd/usdGeom/scope.h>
#include <pxr/usd/usdGeom/xform.h>
-#include <pxr/usd/usdLux/light.h>
+
+#if PXR_VERSION >= 2111
+# include <pxr/usd/usdLux/boundableLightBase.h>
+# include <pxr/usd/usdLux/nonboundableLightBase.h>
+#else
+# include <pxr/usd/usdLux/light.h>
+#endif
#include <iostream>
@@ -55,7 +61,12 @@ USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim
if (params_.import_meshes && prim.IsA<pxr::UsdGeomMesh>()) {
return new USDMeshReader(prim, params_, settings_);
}
+#if PXR_VERSION >= 2111
+ if (params_.import_lights && (prim.IsA<pxr::UsdLuxBoundableLightBase>() ||
+ prim.IsA<pxr::UsdLuxNonboundableLightBase>())) {
+#else
if (params_.import_lights && prim.IsA<pxr::UsdLuxLight>()) {
+#endif
return new USDLightReader(prim, params_, settings_);
}
if (params_.import_volumes && prim.IsA<pxr::UsdVolVolume>()) {
@@ -82,7 +93,11 @@ USDPrimReader *USDStageReader::create_reader(const pxr::UsdPrim &prim)
if (prim.IsA<pxr::UsdGeomMesh>()) {
return new USDMeshReader(prim, params_, settings_);
}
+#if PXR_VERSION >= 2111
+ if (prim.IsA<pxr::UsdLuxBoundableLightBase>() || prim.IsA<pxr::UsdLuxNonboundableLightBase>()) {
+#else
if (prim.IsA<pxr::UsdLuxLight>()) {
+#endif
return new USDLightReader(prim, params_, settings_);
}
if (prim.IsA<pxr::UsdVolVolume>()) {
diff --git a/source/blender/io/usd/intern/usd_reader_volume.cc b/source/blender/io/usd/intern/usd_reader_volume.cc
index aec30539ee6..13044de5002 100644
--- a/source/blender/io/usd/intern/usd_reader_volume.cc
+++ b/source/blender/io/usd/intern/usd_reader_volume.cc
@@ -54,18 +54,6 @@ void USDVolumeReader::read_object_data(Main *bmain, const double motionSampleTim
pxr::UsdVolOpenVDBAsset fieldBase(fieldPrim);
- pxr::UsdAttribute fieldNameAttr = fieldBase.GetFieldNameAttr();
-
- if (fieldNameAttr.IsAuthored()) {
- pxr::TfToken fieldName;
- fieldNameAttr.Get(&fieldName, motionSampleTime);
-
- /* A Blender volume creates density by default. */
- if (fieldName != usdtokens::density) {
- BKE_volume_grid_add(volume, fieldName.GetString().c_str(), VOLUME_GRID_FLOAT);
- }
- }
-
pxr::UsdAttribute filepathAttr = fieldBase.GetFilePathAttr();
if (filepathAttr.IsAuthored()) {
diff --git a/source/blender/io/usd/intern/usd_reader_xform.cc b/source/blender/io/usd/intern/usd_reader_xform.cc
index 4cb7d4e1845..bc6e2dd5297 100644
--- a/source/blender/io/usd/intern/usd_reader_xform.cc
+++ b/source/blender/io/usd/intern/usd_reader_xform.cc
@@ -131,7 +131,7 @@ bool USDXformReader::is_root_xform_prim() const
return false;
}
- if (prim_.IsInMaster()) {
+ if (prim_.IsInPrototype()) {
/* We don't consider prototypes to be root prims,
* because we never want to apply global scaling
* or rotations to the prototypes themselves. */
diff --git a/source/blender/io/usd/intern/usd_writer_light.cc b/source/blender/io/usd/intern/usd_writer_light.cc
index 282393bbcd2..982bc31d767 100644
--- a/source/blender/io/usd/intern/usd_writer_light.cc
+++ b/source/blender/io/usd/intern/usd_writer_light.cc
@@ -33,7 +33,12 @@ void USDLightWriter::do_write(HierarchyContext &context)
pxr::UsdTimeCode timecode = get_export_time_code();
Light *light = static_cast<Light *>(context.object->data);
- pxr::UsdLuxLight usd_light;
+#if PXR_VERSION >= 2111
+ pxr::UsdLuxLightAPI usd_light_api;
+#else
+ pxr::UsdLuxLight usd_light_api;
+
+#endif
switch (light->type) {
case LA_AREA:
@@ -42,21 +47,33 @@ void USDLightWriter::do_write(HierarchyContext &context)
case LA_AREA_ELLIPSE: { /* An ellipse light will deteriorate into a disk light. */
pxr::UsdLuxDiskLight disk_light = pxr::UsdLuxDiskLight::Define(stage, usd_path);
disk_light.CreateRadiusAttr().Set(light->area_size, timecode);
- usd_light = disk_light;
+#if PXR_VERSION >= 2111
+ usd_light_api = disk_light.LightAPI();
+#else
+ usd_light_api = disk_light;
+#endif
break;
}
case LA_AREA_RECT: {
pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path);
rect_light.CreateWidthAttr().Set(light->area_size, timecode);
rect_light.CreateHeightAttr().Set(light->area_sizey, timecode);
- usd_light = rect_light;
+#if PXR_VERSION >= 2111
+ usd_light_api = rect_light.LightAPI();
+#else
+ usd_light_api = rect_light;
+#endif
break;
}
case LA_AREA_SQUARE: {
pxr::UsdLuxRectLight rect_light = pxr::UsdLuxRectLight::Define(stage, usd_path);
rect_light.CreateWidthAttr().Set(light->area_size, timecode);
rect_light.CreateHeightAttr().Set(light->area_size, timecode);
- usd_light = rect_light;
+#if PXR_VERSION >= 2111
+ usd_light_api = rect_light.LightAPI();
+#else
+ usd_light_api = rect_light;
+#endif
break;
}
}
@@ -64,12 +81,23 @@ void USDLightWriter::do_write(HierarchyContext &context)
case LA_LOCAL: {
pxr::UsdLuxSphereLight sphere_light = pxr::UsdLuxSphereLight::Define(stage, usd_path);
sphere_light.CreateRadiusAttr().Set(light->area_size, timecode);
- usd_light = sphere_light;
+#if PXR_VERSION >= 2111
+ usd_light_api = sphere_light.LightAPI();
+#else
+ usd_light_api = sphere_light;
+#endif
break;
}
- case LA_SUN:
- usd_light = pxr::UsdLuxDistantLight::Define(stage, usd_path);
+ case LA_SUN: {
+ pxr::UsdLuxDistantLight distant_light = pxr::UsdLuxDistantLight::Define(stage, usd_path);
+ /* TODO(makowalski): set angle attribute here. */
+#if PXR_VERSION >= 2111
+ usd_light_api = distant_light.LightAPI();
+#else
+ usd_light_api = distant_light;
+#endif
break;
+ }
default:
BLI_assert_msg(0, "is_supported() returned true for unsupported light type");
}
@@ -85,10 +113,10 @@ void USDLightWriter::do_write(HierarchyContext &context)
else {
usd_intensity = light->energy / 100.0f;
}
- usd_light.CreateIntensityAttr().Set(usd_intensity, timecode);
+ usd_light_api.CreateIntensityAttr().Set(usd_intensity, timecode);
- usd_light.CreateColorAttr().Set(pxr::GfVec3f(light->r, light->g, light->b), timecode);
- usd_light.CreateSpecularAttr().Set(light->spec_fac, timecode);
+ usd_light_api.CreateColorAttr().Set(pxr::GfVec3f(light->r, light->g, light->b), timecode);
+ usd_light_api.CreateSpecularAttr().Set(light->spec_fac, timecode);
}
} // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc
index 29ab0479f6e..b548a666ef7 100644
--- a/source/blender/io/usd/intern/usd_writer_material.cc
+++ b/source/blender/io/usd/intern/usd_writer_material.cc
@@ -163,7 +163,7 @@ void create_usd_preview_surface_material(const USDExporterContext &usd_export_co
created_shader = create_usd_preview_shader(usd_export_context, usd_material, input_node);
preview_surface.CreateInput(input_spec.input_name, input_spec.input_type)
- .ConnectToSource(created_shader, input_spec.source_name);
+ .ConnectToSource(created_shader.ConnectableAPI(), input_spec.source_name);
}
else if (input_spec.set_default_value) {
/* Set hardcoded value. */
@@ -217,7 +217,7 @@ void create_usd_viewport_material(const USDExporterContext &usd_export_context,
shader.CreateInput(usdtokens::metallic, pxr::SdfValueTypeNames->Float).Set(material->metallic);
/* Connect the shader and the material together. */
- usd_material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface);
+ usd_material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), usdtokens::surface);
}
/* Return USD Preview Surface input map singleton. */
@@ -293,12 +293,12 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context,
uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token)
.Set(pxr::TfToken(uv_set));
usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2)
- .ConnectToSource(uv_shader, usdtokens::result);
+ .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result);
}
else {
uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token).Set(default_uv);
usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2)
- .ConnectToSource(uv_shader, usdtokens::result);
+ .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result);
}
}
@@ -313,7 +313,7 @@ static void create_uvmap_shader(const USDExporterContext &usd_export_context,
if (uv_shader.GetPrim().IsValid()) {
uv_shader.CreateInput(usdtokens::varname, pxr::SdfValueTypeNames->Token).Set(default_uv);
usd_tex_shader.CreateInput(usdtokens::st, pxr::SdfValueTypeNames->Float2)
- .ConnectToSource(uv_shader, usdtokens::result);
+ .ConnectToSource(uv_shader.ConnectableAPI(), usdtokens::result);
}
}
}
@@ -488,7 +488,7 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u
case SH_NODE_BSDF_DIFFUSE:
case SH_NODE_BSDF_PRINCIPLED: {
shader.CreateIdAttr(pxr::VtValue(usdtokens::preview_surface));
- material.CreateSurfaceOutput().ConnectToSource(shader, usdtokens::surface);
+ material.CreateSurfaceOutput().ConnectToSource(shader.ConnectableAPI(), usdtokens::surface);
break;
}
diff --git a/source/blender/io/wavefront_obj/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt
index 8045d51e0da..cc375577b52 100644
--- a/source/blender/io/wavefront_obj/CMakeLists.txt
+++ b/source/blender/io/wavefront_obj/CMakeLists.txt
@@ -13,6 +13,7 @@ set(INC
../../makesrna
../../nodes
../../windowmanager
+ ../../../../extern/fmtlib/include
../../../../intern/guardedalloc
)
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
index 3bee93b36a5..0095384609a 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh
@@ -8,7 +8,6 @@
#include <cstdio>
#include <string>
-#include <system_error>
#include <type_traits>
#include <vector>
@@ -17,6 +16,11 @@
#include "BLI_string_ref.hh"
#include "BLI_utility_mixins.hh"
+/* SEP macro from BLI path utils clashes with SEP symbol in fmt headers. */
+#undef SEP
+#define FMT_HEADER_ONLY
+#include <fmt/format.h>
+
namespace blender::io::obj {
enum class eFileType {
@@ -124,40 +128,40 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key
{
switch (key) {
case eOBJSyntaxElement::vertex_coords: {
- return {"v %f %f %f\n", 3, is_type_float<T...>};
+ return {"v {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
}
case eOBJSyntaxElement::uv_vertex_coords: {
- return {"vt %f %f\n", 2, is_type_float<T...>};
+ return {"vt {:.6f} {:.6f}\n", 2, is_type_float<T...>};
}
case eOBJSyntaxElement::normal: {
- return {"vn %.4f %.4f %.4f\n", 3, is_type_float<T...>};
+ return {"vn {:.4f} {:.4f} {:.4f}\n", 3, is_type_float<T...>};
}
case eOBJSyntaxElement::poly_element_begin: {
return {"f", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::vertex_uv_normal_indices: {
- return {" %d/%d/%d", 3, is_type_integral<T...>};
+ return {" {}/{}/{}", 3, is_type_integral<T...>};
}
case eOBJSyntaxElement::vertex_normal_indices: {
- return {" %d//%d", 2, is_type_integral<T...>};
+ return {" {}//{}", 2, is_type_integral<T...>};
}
case eOBJSyntaxElement::vertex_uv_indices: {
- return {" %d/%d", 2, is_type_integral<T...>};
+ return {" {}/{}", 2, is_type_integral<T...>};
}
case eOBJSyntaxElement::vertex_indices: {
- return {" %d", 1, is_type_integral<T...>};
+ return {" {}", 1, is_type_integral<T...>};
}
case eOBJSyntaxElement::poly_usemtl: {
- return {"usemtl %s\n", 1, is_type_string_related<T...>};
+ return {"usemtl {}\n", 1, is_type_string_related<T...>};
}
case eOBJSyntaxElement::edge: {
- return {"l %d %d\n", 2, is_type_integral<T...>};
+ return {"l {} {}\n", 2, is_type_integral<T...>};
}
case eOBJSyntaxElement::cstype: {
return {"cstype bspline\n", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_degree: {
- return {"deg %d\n", 1, is_type_integral<T...>};
+ return {"deg {}\n", 1, is_type_integral<T...>};
}
case eOBJSyntaxElement::curve_element_begin: {
return {"curv 0.0 1.0", 0, is_type_string_related<T...>};
@@ -166,7 +170,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key
return {"parm u 0.0", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::nurbs_parameters: {
- return {" %f", 1, is_type_float<T...>};
+ return {" {:.6f}", 1, is_type_float<T...>};
}
case eOBJSyntaxElement::nurbs_parameter_end: {
return {" 1.0\n", 0, is_type_string_related<T...>};
@@ -184,19 +188,19 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key
return {"\n", 0, is_type_string_related<T...>};
}
case eOBJSyntaxElement::mtllib: {
- return {"mtllib %s\n", 1, is_type_string_related<T...>};
+ return {"mtllib {}\n", 1, is_type_string_related<T...>};
}
case eOBJSyntaxElement::smooth_group: {
- return {"s %d\n", 1, is_type_integral<T...>};
+ return {"s {}\n", 1, is_type_integral<T...>};
}
case eOBJSyntaxElement::object_group: {
- return {"g %s\n", 1, is_type_string_related<T...>};
+ return {"g {}\n", 1, is_type_string_related<T...>};
}
case eOBJSyntaxElement::object_name: {
- return {"o %s\n", 1, is_type_string_related<T...>};
+ return {"o {}\n", 1, is_type_string_related<T...>};
}
case eOBJSyntaxElement::string: {
- return {"%s", 1, is_type_string_related<T...>};
+ return {"{}", 1, is_type_string_related<T...>};
}
}
}
@@ -206,56 +210,56 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key
{
switch (key) {
case eMTLSyntaxElement::newmtl: {
- return {"newmtl %s\n", 1, is_type_string_related<T...>};
+ return {"newmtl {}\n", 1, is_type_string_related<T...>};
}
case eMTLSyntaxElement::Ni: {
- return {"Ni %.6f\n", 1, is_type_float<T...>};
+ return {"Ni {:.6f}\n", 1, is_type_float<T...>};
}
case eMTLSyntaxElement::d: {
- return {"d %.6f\n", 1, is_type_float<T...>};
+ return {"d {:.6f}\n", 1, is_type_float<T...>};
}
case eMTLSyntaxElement::Ns: {
- return {"Ns %.6f\n", 1, is_type_float<T...>};
+ return {"Ns {:.6f}\n", 1, is_type_float<T...>};
}
case eMTLSyntaxElement::illum: {
- return {"illum %d\n", 1, is_type_integral<T...>};
+ return {"illum {}\n", 1, is_type_integral<T...>};
}
case eMTLSyntaxElement::Ka: {
- return {"Ka %.6f %.6f %.6f\n", 3, is_type_float<T...>};
+ return {"Ka {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
}
case eMTLSyntaxElement::Kd: {
- return {"Kd %.6f %.6f %.6f\n", 3, is_type_float<T...>};
+ return {"Kd {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
}
case eMTLSyntaxElement::Ks: {
- return {"Ks %.6f %.6f %.6f\n", 3, is_type_float<T...>};
+ return {"Ks {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
}
case eMTLSyntaxElement::Ke: {
- return {"Ke %.6f %.6f %.6f\n", 3, is_type_float<T...>};
+ return {"Ke {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>};
}
/* Keep only one space between options since filepaths may have leading spaces too. */
case eMTLSyntaxElement::map_Kd: {
- return {"map_Kd %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_Kd {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_Ks: {
- return {"map_Ks %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_Ks {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_Ns: {
- return {"map_Ns %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_Ns {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_d: {
- return {"map_d %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_d {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_refl: {
- return {"map_refl %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_refl {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_Ke: {
- return {"map_Ke %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_Ke {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::map_Bump: {
- return {"map_Bump %s %s\n", 2, is_type_string_related<T...>};
+ return {"map_Bump {} {}\n", 2, is_type_string_related<T...>};
}
case eMTLSyntaxElement::string: {
- return {"%s", 1, is_type_string_related<T...>};
+ return {"{}", 1, is_type_string_related<T...>};
}
}
}
@@ -270,9 +274,7 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key
* Call write_fo_file once in a while to write the memory buffer(s)
* into the given file.
*/
-template<eFileType filetype,
- size_t buffer_chunk_size = 64 * 1024,
- size_t write_local_buffer_size = 1024>
+template<eFileType filetype, size_t buffer_chunk_size = 64 * 1024>
class FormatHandler : NonCopyable, NonMovable {
private:
typedef std::vector<char> VectorChar;
@@ -299,7 +301,7 @@ class FormatHandler : NonCopyable, NonMovable {
return blocks_.size();
}
- void append_from(FormatHandler<filetype, buffer_chunk_size, write_local_buffer_size> &v)
+ void append_from(FormatHandler<filetype, buffer_chunk_size> &v)
{
blocks_.insert(blocks_.end(),
std::make_move_iterator(v.blocks_.begin()),
@@ -328,33 +330,6 @@ class FormatHandler : NonCopyable, NonMovable {
}
private:
- /* Remove this after upgrading to C++20. */
- template<typename T> using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
-
- /**
- * Make #std::string etc., usable for `fprintf` family. int float etc. are not affected.
- * \return: `const char *` or the original argument if the argument is
- * not related to #std::string.
- */
- template<typename T> constexpr auto convert_to_primitive(T &&arg) const
- {
- if constexpr (std::is_same_v<remove_cvref_t<T>, std::string> ||
- std::is_same_v<remove_cvref_t<T>, blender::StringRefNull>) {
- return arg.c_str();
- }
- else if constexpr (std::is_same_v<remove_cvref_t<T>, blender::StringRef>) {
- BLI_STATIC_ASSERT(
- (always_false<T>::value),
- "Null-terminated string not present. Please use blender::StringRefNull instead.");
- /* Another trick to cause a compile-time error: returning nothing to #std::printf. */
- return;
- }
- else {
- /* For int, float etc. */
- return std::forward<T>(arg);
- }
- }
-
/* Ensure the last block contains at least this amount of free space.
* If not, add a new block with max of block size & the amount of space needed. */
void ensure_space(size_t at_least)
@@ -365,38 +340,15 @@ class FormatHandler : NonCopyable, NonMovable {
}
}
- template<typename... T> constexpr void write_impl(const char *fmt, T &&...args)
+ template<typename... T> void write_impl(const char *fmt, T &&...args)
{
- if constexpr (sizeof...(T) == 0) {
- /* No arguments: just emit the format string. */
- size_t len = strlen(fmt);
- ensure_space(len);
- VectorChar &bb = blocks_.back();
- bb.insert(bb.end(), fmt, fmt + len);
- }
- else {
- /* Format into a local buffer. */
- char buf[write_local_buffer_size];
- int needed = std::snprintf(
- buf, write_local_buffer_size, fmt, convert_to_primitive(std::forward<T>(args))...);
- if (needed < 0)
- throw std::system_error(
- errno, std::system_category(), "Failed to format obj export string into a buffer");
- ensure_space(needed + 1); /* Ensure space for zero terminator. */
- VectorChar &bb = blocks_.back();
- if (needed < write_local_buffer_size) {
- /* String formatted successfully into the local buffer, copy it. */
- bb.insert(bb.end(), buf, buf + needed);
- }
- else {
- /* Would need more space than the local buffer: insert said space and format again into
- * that. */
- size_t bbEnd = bb.size();
- bb.insert(bb.end(), needed, ' ');
- std::snprintf(
- bb.data() + bbEnd, needed + 1, fmt, convert_to_primitive(std::forward<T>(args))...);
- }
- }
+ /* Format into a local buffer. */
+ fmt::memory_buffer buf;
+ fmt::format_to(fmt::appender(buf), fmt, std::forward<T>(args)...);
+ size_t len = buf.size();
+ ensure_space(len);
+ VectorChar &bb = blocks_.back();
+ bb.insert(bb.end(), buf.begin(), buf.end());
}
};
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index fb9074999f9..8c9b04a5ac3 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -33,7 +33,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
{
/* We need to copy the object because it may be in temporary space. */
Object *obj_eval = DEG_get_evaluated_object(depsgraph, mesh_object);
- export_object_eval_ = *obj_eval;
+ export_object_eval_ = dna::shallow_copy(*obj_eval);
export_mesh_eval_ = export_params.apply_modifiers ?
BKE_object_get_evaluated_mesh(&export_object_eval_) :
BKE_object_get_pre_modified_mesh(&export_object_eval_);
@@ -89,7 +89,7 @@ std::pair<Mesh *, bool> OBJMesh::triangulate_mesh_eval()
if (export_mesh_eval_->totpoly <= 0) {
return {export_mesh_eval_, false};
}
- const BMeshCreateParams bm_create_params = {0u};
+ const BMeshCreateParams bm_create_params = {false};
BMeshFromMeshParams bm_convert_params{};
bm_convert_params.calc_face_normal = true;
bm_convert_params.calc_vert_normal = true;
diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
index b8fecfb25f3..7e3a9228c3b 100644
--- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc
@@ -241,7 +241,7 @@ TEST(obj_exporter_writer, mtllib)
TEST(obj_exporter_writer, format_handler_buffer_chunking)
{
/* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */
- FormatHandler<eFileType::OBJ, 16, 8> h;
+ FormatHandler<eFileType::OBJ, 16> h;
h.write<eOBJSyntaxElement::object_name>("abc");
h.write<eOBJSyntaxElement::object_name>("abcd");
h.write<eOBJSyntaxElement::object_name>("abcde");
diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h
index f1626781fc6..97cc588e639 100644
--- a/source/blender/makesdna/DNA_curves_types.h
+++ b/source/blender/makesdna/DNA_curves_types.h
@@ -28,6 +28,7 @@ typedef enum CurveType {
CURVE_TYPE_BEZIER = 2,
CURVE_TYPE_NURBS = 3,
} CurveType;
+#define CURVE_TYPES_NUM 4
typedef enum HandleType {
/** The handle can be moved anywhere, and doesn't influence the point's other handle. */
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index ad2ef05da13..cf43574af55 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -52,7 +52,7 @@ typedef struct CustomDataLayer {
typedef struct CustomDataExternal {
/** FILE_MAX. */
- char filename[1024];
+ char filepath[1024];
} CustomDataExternal;
/**
diff --git a/source/blender/makesdna/DNA_defs.h b/source/blender/makesdna/DNA_defs.h
index b4230209dd5..bfeb809b369 100644
--- a/source/blender/makesdna/DNA_defs.h
+++ b/source/blender/makesdna/DNA_defs.h
@@ -46,3 +46,100 @@
/* non-id name variables should use this length */
#define MAX_NAME 64
+
+/* #DNA_DEFINE_CXX_METHODS is used to define C++ methods which are needed for proper/safe resource
+ * management, making unsafe (from an ownership perspective: i.e. pointers which sometimes needs to
+ * be set to nullptr on copy, sometimes needs to be dupalloc-ed) operations explicit, and taking
+ * care of compiler specific warnings when dealing with members marked with DNA_DEPRECATED.
+ *
+ * The `class_name` argument is to match the structure name the macro is used from.
+ *
+ * Typical usage example:
+ *
+ * typedef struct Object {
+ * DNA_DEFINE_CXX_METHODS(Object)
+ * } Object;
+ */
+#ifndef __cplusplus
+# define DNA_DEFINE_CXX_METHODS(class_name)
+#else
+
+/* Forward-declared here since there is no simple header file to be pulled for this functionality.
+ * Avoids pulling `string.h` from this header to get access to #memcpy. */
+extern "C" void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
+extern "C" void _DNA_internal_memzero(void *dst, size_t size);
+
+namespace blender::dna::internal {
+
+template<class T> class ShallowDataConstRef {
+ public:
+ constexpr explicit ShallowDataConstRef(const T &ref) : ref_(ref)
+ {
+ }
+
+ inline const T *get_pointer() const
+ {
+ return &ref_;
+ }
+
+ private:
+ const T &ref_;
+};
+
+} // namespace blender::dna::internal
+
+# define DNA_DEFINE_CXX_METHODS(class_name) \
+ class_name() = default; \
+ ~class_name() = default; \
+ /* Delete copy and assignment, which are not safe for resource ownership. */ \
+ class_name(const class_name &other) = delete; \
+ class_name(class_name &&other) noexcept = delete; \
+ class_name &operator=(const class_name &other) = delete; \
+ class_name &operator=(class_name &&other) = delete; \
+ /* Support for shallow copy. */ \
+ /* NOTE: Calling the default constructor works-around deprecated warning generated by GCC. */ \
+ class_name(const blender::dna::internal::ShallowDataConstRef<class_name> ref) : class_name() \
+ { \
+ _DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \
+ } \
+ class_name &operator=(const blender::dna::internal::ShallowDataConstRef<class_name> ref) \
+ { \
+ if (this != ref.get_pointer()) { \
+ _DNA_internal_memcpy(this, ref.get_pointer(), sizeof(class_name)); \
+ } \
+ return *this; \
+ }
+
+namespace blender::dna {
+
+/* Creates shallow copy of the given object.
+ * The entire object is copied as-is using memory copy.
+ *
+ * Typical usage:
+ * Object temp_object = blender::dna::shallow_copy(*input_object);
+ *
+ * From the implementation detail go via copy constructor/assign operator defined in the structure.
+ */
+template<class T>
+[[nodiscard]] inline internal::ShallowDataConstRef<T> shallow_copy(const T &other)
+{
+ return internal::ShallowDataConstRef(other);
+}
+
+/* Fill underlying memory used by DNA object with zeroes. */
+template<class T> inline void zero_memory(T &object)
+{
+ /* TODO(sergey): Consider adding static assert for T being a trivial type. */
+ _DNA_internal_memzero(&object, sizeof(T));
+}
+
+/* Copy memory from one DNA object to another. */
+template<class T> inline void copy_memory(T &dst, const T &src)
+{
+ /* TODO(sergey): Consider adding static assert for T being a trivial type. */
+ _DNA_internal_memcpy(&dst, &src, sizeof(T));
+}
+
+} // namespace blender::dna
+
+#endif
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index 3e06259dfd5..9d14ca039ac 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -193,7 +193,7 @@
.vgname = "", \
.pass_index = 0, \
.flag = GP_SMOOTH_MOD_LOCATION, \
- .factor = 0.5f, \
+ .factor = 1.0f, \
.step = 1, \
.layer_pass = 0, \
.curve_intensity = NULL, \
@@ -366,5 +366,14 @@
.smooth_step = 1, \
}
+#define _DNA_DEFAULT_EnvelopeGpencilModifierData \
+ { \
+ .spread = 10, \
+ .mode = GP_ENVELOPE_SEGMENTS, \
+ .mat_nr = -1, \
+ .thickness = 1.0f, \
+ .strength = 1.0f, \
+ }
+
/* clang-format off */
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index 0539b84e093..7568dc5ff9a 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -46,6 +46,7 @@ typedef enum GpencilModifierType {
eGpencilModifierType_Dash = 22,
eGpencilModifierType_WeightAngle = 23,
eGpencilModifierType_Shrinkwrap = 24,
+ eGpencilModifierType_Envelope = 25,
/* Keep last. */
NUM_GREASEPENCIL_MODIFIER_TYPES,
} GpencilModifierType;
@@ -521,7 +522,7 @@ typedef struct DashGpencilModifierSegment {
float radius;
float opacity;
int mat_nr;
- int _pad;
+ int flag;
} DashGpencilModifierSegment;
typedef struct DashGpencilModifierData {
@@ -545,6 +546,14 @@ typedef struct DashGpencilModifierData {
} DashGpencilModifierData;
+typedef enum eDashGpencil_Flag {
+ GP_DASH_INVERT_LAYER = (1 << 0),
+ GP_DASH_INVERT_PASS = (1 << 1),
+ GP_DASH_INVERT_LAYERPASS = (1 << 2),
+ GP_DASH_INVERT_MATERIAL = (1 << 3),
+ GP_DASH_USE_CYCLIC = (1 << 7),
+} eDashGpencil_Flag;
+
typedef struct MirrorGpencilModifierData {
GpencilModifierData modifier;
struct Object *object;
@@ -749,6 +758,7 @@ typedef enum eSmoothGpencil_Flag {
GP_SMOOTH_INVERT_LAYERPASS = (1 << 7),
GP_SMOOTH_INVERT_MATERIAL = (1 << 4),
GP_SMOOTH_CUSTOM_CURVE = (1 << 8),
+ GP_SMOOTH_KEEP_SHAPE = (1 << 9),
} eSmoothGpencil_Flag;
typedef struct ArmatureGpencilModifierData {
@@ -1127,6 +1137,46 @@ typedef enum eShrinkwrapGpencil_Flag {
GP_SHRINKWRAP_INVERT_VGROUP = (1 << 6),
} eShrinkwrapGpencil_Flag;
+typedef struct EnvelopeGpencilModifierData {
+ GpencilModifierData modifier;
+ /** Material for filtering. */
+ struct Material *material;
+ /** Layer name. */
+ char layername[64];
+ /** Optional vertexgroup name, MAX_VGROUP_NAME. */
+ char vgname[64];
+ /** Custom index for passes. */
+ int pass_index;
+ /** Several flags. */
+ int flag;
+ int mode;
+ /** Material for the new strokes. */
+ int mat_nr;
+ /** Thickness multiplier for the new strokes. */
+ float thickness;
+ /** Strength multiplier for the new strokes. */
+ float strength;
+ /** Custom index for passes. */
+ int layer_pass;
+ /* Length of the envelope effect. */
+ int spread;
+} EnvelopeGpencilModifierData;
+
+typedef enum eEnvelopeGpencil_Flag {
+ GP_ENVELOPE_INVERT_LAYER = (1 << 0),
+ GP_ENVELOPE_INVERT_PASS = (1 << 1),
+ GP_ENVELOPE_INVERT_VGROUP = (1 << 2),
+ GP_ENVELOPE_INVERT_LAYERPASS = (1 << 3),
+ GP_ENVELOPE_INVERT_MATERIAL = (1 << 4),
+} eEnvelopeGpencil_Flag;
+
+/* Texture->mode */
+typedef enum eEnvelopeGpencil_Mode {
+ GP_ENVELOPE_DEFORM = 0,
+ GP_ENVELOPE_SEGMENTS = 1,
+ GP_ENVELOPE_FILLS = 2,
+} eEnvelopeGpencil_Mode;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h
index 299ac4e2fbe..77730ce254c 100644
--- a/source/blender/makesdna/DNA_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_modifier_defaults.h
@@ -309,7 +309,7 @@
.falloff = 0.0f, \
.curfalloff = NULL, \
.indexar = NULL, \
- .totindex = 0, \
+ .indexar_num = 0, \
.force = 1.0f, \
.name = "", \
}
@@ -317,7 +317,7 @@
#define _DNA_DEFAULT_LaplacianDeformModifierData \
{ \
.anchor_grp_name = "", \
- .total_verts = 0, \
+ .verts_num = 0, \
.repeat = 1, \
.vertexco = NULL, \
.cache_system = NULL, \
@@ -381,13 +381,13 @@
.bindinfluences = NULL, \
.bindoffsets = NULL, \
.bindcagecos = NULL, \
- .totvert = 0, \
- .totcagevert = 0, \
+ .verts_num = 0, \
+ .cage_verts_num = 0, \
.dyngrid = NULL, \
.dyninfluences = NULL, \
.dynverts = NULL, \
.dyngridsize = 0, \
- .totinfluence = 0, \
+ .influences_num = 0, \
.dyncellmin = {0.0f, 0.0f, 0.0f}, \
.dyncellwidth = 0.0f, \
.bindmat = _DNA_DEFAULT_UNIT_M4, \
@@ -621,7 +621,7 @@
.mesh = NULL, \
.bvhtree = NULL, \
.cfra = 0, \
- .numverts = 0, \
+ .verts_num = 0, \
}
#define _DNA_DEFAULT_SurfaceDeformModifierData \
@@ -630,9 +630,9 @@
.target = NULL, \
.verts = NULL, \
.falloff = 4.0f, \
- .num_mesh_verts = 0, \
- .num_bind_verts = 0, \
- .numpoly = 0, \
+ .mesh_verts_num = 0, \
+ .bind_verts_num = 0, \
+ .polys_num = 0, \
.flags = 0, \
.mat = _DNA_DEFAULT_UNIT_M4, \
.strength = 1.0f, \
@@ -650,7 +650,7 @@
#define _DNA_DEFAULT_UVProjectModifierData \
{ \
.projectors = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}, \
- .num_projectors = 1, \
+ .projectors_num = 1, \
.aspectx = 1.0f, \
.aspecty = 1.0f, \
.scalex = 1.0f, \
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 470497aabce..73c4eeaaab3 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -617,7 +617,7 @@ typedef struct UVProjectModifierData {
*/
struct Object *projectors[10];
char _pad2[4];
- int num_projectors;
+ int projectors_num;
float aspectx, aspecty;
float scalex, scaley;
/** MAX_CUSTOMDATA_LAYER_NAME. */
@@ -812,7 +812,7 @@ typedef struct HookModifierData {
/** If NULL, it's using vertexgroup. */
int *indexar;
- int totindex;
+ int indexar_num;
float force;
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
char name[64];
@@ -895,7 +895,7 @@ typedef struct SurfaceModifierData {
/** Bounding volume hierarchy of the mesh faces. */
struct BVHTreeFromMesh *bvhtree;
- int cfra, numverts;
+ int cfra, verts_num;
} SurfaceModifierData;
typedef struct BooleanModifierData {
@@ -945,7 +945,7 @@ typedef struct MDefInfluence {
typedef struct MDefCell {
int offset;
- int totinfluence;
+ int influences_num;
} MDefCell;
typedef struct MeshDeformModifierData {
@@ -967,7 +967,7 @@ typedef struct MeshDeformModifierData {
/** Coordinates that cage was bound with. */
float *bindcagecos;
/** Total vertices in mesh and cage. */
- int totvert, totcagevert;
+ int verts_num, cage_verts_num;
/* result of dynamic binding */
/** Grid with dynamic binding cell points. */
@@ -979,7 +979,7 @@ typedef struct MeshDeformModifierData {
/** Size of the dynamic bind grid. */
int dyngridsize;
/** Total number of vertex influences. */
- int totinfluence;
+ int influences_num;
/** Offset of the dynamic bind grid. */
float dyncellmin[3];
/** Width of dynamic bind cell. */
@@ -998,7 +998,7 @@ typedef struct MeshDeformModifierData {
struct MeshDeformModifierData *mmd,
struct Mesh *cagemesh,
float *vertexcos,
- int totvert,
+ int verts_num,
float cagemat[4][4]);
} MeshDeformModifierData;
@@ -2018,7 +2018,7 @@ typedef struct LaplacianDeformModifierData {
ModifierData modifier;
/** MAX_VGROUP_NAME. */
char anchor_grp_name[64];
- int total_verts, repeat;
+ int verts_num, repeat;
float *vertexco;
/** Runtime only. */
void *cache_system;
@@ -2201,7 +2201,7 @@ enum {
typedef struct SDefBind {
unsigned int *vert_inds;
- unsigned int numverts;
+ unsigned int verts_num;
int mode;
float *vert_weights;
float normal_dist;
@@ -2210,7 +2210,7 @@ typedef struct SDefBind {
typedef struct SDefVert {
SDefBind *binds;
- unsigned int numbinds;
+ unsigned int binds_num;
unsigned int vertex_idx;
} SDefVert;
@@ -2223,7 +2223,7 @@ typedef struct SurfaceDeformModifierData {
/** Vertex bind data. */
SDefVert *verts;
float falloff;
- unsigned int num_mesh_verts, num_bind_verts, numpoly;
+ unsigned int mesh_verts_num, bind_verts_num, polys_num;
int flags;
float mat[4][4];
float strength;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 99d7e15fa7a..73539bea8ee 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1189,7 +1189,7 @@ typedef struct NodeCryptomatte {
/** Legacy attributes */
/* Number of input sockets. */
- int num_inputs;
+ int inputs_num;
char _pad[4];
NodeCryptomatte_Runtime runtime;
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 9e0bf7dcc5a..838a4ed2818 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -203,7 +203,7 @@ typedef struct Object_Runtime {
float (*crazyspace_deform_imats)[3][3];
float (*crazyspace_deform_cos)[3];
- int crazyspace_num_verts;
+ int crazyspace_verts_num;
int _pad3[3];
} Object_Runtime;
@@ -233,6 +233,8 @@ enum eObjectLineArt_Flags {
};
typedef struct Object {
+ DNA_DEFINE_CXX_METHODS(Object)
+
ID id;
/** Animation data (must be immediately after id for utilities to use it). */
struct AnimData *adt;
diff --git a/source/blender/makesdna/DNA_particle_defaults.h b/source/blender/makesdna/DNA_particle_defaults.h
index 138aa6f1f98..108252a5e6c 100644
--- a/source/blender/makesdna/DNA_particle_defaults.h
+++ b/source/blender/makesdna/DNA_particle_defaults.h
@@ -56,8 +56,8 @@
.rotmode = PART_ROT_VEL, \
.avemode = PART_AVE_VELOCITY, \
\
- .child_nbr = 10, \
- .ren_child_nbr = 100, \
+ .child_percent = 10, \
+ .child_render_percent = 100, \
.childrad = 0.2f, \
.childflat = 0.0f, \
.clumppow = 0.0f, \
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 397385c0f5b..f3d342e4849 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -226,7 +226,7 @@ typedef struct ParticleSettings {
/* children */
int child_flag;
char _pad3[4];
- int child_nbr, ren_child_nbr;
+ int child_percent, child_render_percent;
float parents, childsize, childrandsize;
float childrad, childflat;
/* clumping */
diff --git a/source/blender/makesdna/DNA_pointcache_types.h b/source/blender/makesdna/DNA_pointcache_types.h
index b247176f537..1133237199b 100644
--- a/source/blender/makesdna/DNA_pointcache_types.h
+++ b/source/blender/makesdna/DNA_pointcache_types.h
@@ -131,7 +131,7 @@ enum {
PTCACHE_FRAMES_SKIPPED = 1 << 8,
PTCACHE_EXTERNAL = 1 << 9,
PTCACHE_READ_INFO = 1 << 10,
- /** Don't use the filename of the blend-file the data is linked from (write a local cache). */
+ /** Don't use the file-path of the blend-file the data is linked from (write a local cache). */
PTCACHE_IGNORE_LIBPATH = 1 << 11,
/**
* High resolution cache is saved for smoke for backwards compatibility,
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 24c120ae860..d0c23f5d452 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -465,6 +465,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_XVID 32
#define R_IMF_IMTYPE_THEORA 33
#define R_IMF_IMTYPE_PSD 34
+#define R_IMF_IMTYPE_WEBP 35
#define R_IMF_IMTYPE_INVALID 255
@@ -1989,7 +1990,7 @@ enum {
/* sequencer seq_prev_type seq_rend_type */
-/** #RenderData.engine (scene.c) */
+/** #RenderData.engine (scene.cc) */
extern const char *RE_engine_id_BLENDER_EEVEE;
extern const char *RE_engine_id_BLENDER_WORKBENCH;
extern const char *RE_engine_id_CYCLES;
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index c8209b4d194..d32757cc868 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -540,6 +540,8 @@ enum {
AREA_FLAG_STACKED_FULLSCREEN = (1 << 7),
/** Update action zones (even if the mouse is not intersecting them). */
AREA_FLAG_ACTIONZONES_UPDATE = (1 << 8),
+ /** For offscreen areas. */
+ AREA_FLAG_OFFSCREEN = (1 << 9),
};
#define AREAGRID 4
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index c3335f7959e..6d7952cb799 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -309,7 +309,6 @@ typedef enum eSpaceOutliner_Flag {
typedef enum eSpaceOutliner_Filter {
SO_FILTER_SEARCH = (1 << 0), /* Run-time flag. */
SO_FILTER_CLEARED_1 = (1 << 1),
- SO_FILTER_NO_LIB_OVERRIDE = SO_FILTER_CLEARED_1, /* re-use */
SO_FILTER_NO_OBJECT = (1 << 2),
SO_FILTER_NO_OB_CONTENT = (1 << 3), /* Not only mesh, but modifiers, constraints, ... */
SO_FILTER_NO_CHILDREN = (1 << 4),
@@ -345,7 +344,7 @@ typedef enum eSpaceOutliner_Filter {
#define SO_FILTER_ANY \
(SO_FILTER_NO_OB_CONTENT | SO_FILTER_NO_CHILDREN | SO_FILTER_OB_TYPE | SO_FILTER_OB_STATE | \
- SO_FILTER_NO_COLLECTION | SO_FILTER_NO_VIEW_LAYERS | SO_FILTER_NO_LIB_OVERRIDE)
+ SO_FILTER_NO_COLLECTION | SO_FILTER_NO_VIEW_LAYERS)
/** #SpaceOutliner.filter_state */
typedef enum eSpaceOutliner_StateFilter {
@@ -990,12 +989,6 @@ typedef enum eFileSelectType {
FILE_SPECIAL = 9,
} eFileSelectType;
-/** File-selector op property -> action. */
-typedef enum eFileSel_Action {
- FILE_OPENFILE = 0,
- FILE_SAVE = 1,
-} eFileSel_Action;
-
/**
* #FileSelectParams.flag / `sfile->params->flag`.
* \note short flag, also used as 16 lower bits of flags in link/append code
@@ -1141,8 +1134,8 @@ typedef struct FileDirEntry {
#
typedef struct FileDirEntryArr {
ListBase entries;
- int nbr_entries;
- int nbr_entries_filtered;
+ int entries_num;
+ int entries_filtered_num;
/** FILE_MAX. */
char root[1024];
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 94b2514d423..99938d711ee 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -649,8 +649,9 @@ typedef struct UserDef_Experimental {
char use_extended_asset_browser;
char use_override_templates;
char use_named_attribute_nodes;
+ char use_select_nearest_on_first_click;
char enable_eevee_next;
- char _pad[2];
+ char _pad[1];
/** `makesdna` does not allow empty structs. */
} UserDef_Experimental;
diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt
index e507831424f..2afaf04a8d7 100644
--- a/source/blender/makesdna/intern/CMakeLists.txt
+++ b/source/blender/makesdna/intern/CMakeLists.txt
@@ -122,10 +122,10 @@ set(SRC
../DNA_camera_defaults.h
../DNA_collection_defaults.h
../DNA_curve_defaults.h
+ ../DNA_curves_defaults.h
../DNA_defaults.h
../DNA_fluid_defaults.h
../DNA_gpencil_modifier_defaults.h
- ../DNA_curves_defaults.h
../DNA_image_defaults.h
../DNA_lattice_defaults.h
../DNA_light_defaults.h
diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c
index b7f942e2502..197a863db72 100644
--- a/source/blender/makesdna/intern/dna_defaults.c
+++ b/source/blender/makesdna/intern/dna_defaults.c
@@ -316,6 +316,7 @@ SDNA_DEFAULT_DECL_STRUCT(LengthGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierData);
SDNA_DEFAULT_DECL_STRUCT(DashGpencilModifierSegment);
SDNA_DEFAULT_DECL_STRUCT(ShrinkwrapGpencilModifierData);
+SDNA_DEFAULT_DECL_STRUCT(EnvelopeGpencilModifierData);
#undef SDNA_DEFAULT_DECL_STRUCT
@@ -555,6 +556,7 @@ const void *DNA_default_table[SDNA_TYPE_MAX] = {
SDNA_DEFAULT_DECL(DashGpencilModifierData),
SDNA_DEFAULT_DECL(DashGpencilModifierSegment),
SDNA_DEFAULT_DECL(ShrinkwrapGpencilModifierData),
+ SDNA_DEFAULT_DECL(EnvelopeGpencilModifierData),
};
#undef SDNA_DEFAULT_DECL
#undef SDNA_DEFAULT_DECL_EX
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index 7b155df3084..86649357433 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -61,6 +61,7 @@ DNA_STRUCT_RENAME_ELEM(Curve, ext1, extrude)
DNA_STRUCT_RENAME_ELEM(Curve, ext2, bevel_radius)
DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32)
DNA_STRUCT_RENAME_ELEM(Curve, width, offset)
+DNA_STRUCT_RENAME_ELEM(CustomDataExternal, filename, filepath)
DNA_STRUCT_RENAME_ELEM(Editing, over_border, overlay_frame_rect)
DNA_STRUCT_RENAME_ELEM(Editing, over_cfra, overlay_frame_abs)
DNA_STRUCT_RENAME_ELEM(Editing, over_flag, overlay_frame_flag)
@@ -73,29 +74,45 @@ DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_parent, guide_parent)
DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_source, guide_source)
DNA_STRUCT_RENAME_ELEM(FluidDomainSettings, guiding_vel_factor, guide_vel_factor)
DNA_STRUCT_RENAME_ELEM(FluidEffectorSettings, guiding_mode, guide_mode)
+DNA_STRUCT_RENAME_ELEM(HookModifierData, totindex, indexar_num)
DNA_STRUCT_RENAME_ELEM(Image, name, filepath)
+DNA_STRUCT_RENAME_ELEM(LaplacianDeformModifierData, total_verts, verts_num)
DNA_STRUCT_RENAME_ELEM(Library, name, filepath)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, mask_switches)
DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits)
+DNA_STRUCT_RENAME_ELEM(MDefCell, totinfluence, influences_num)
DNA_STRUCT_RENAME_ELEM(MaskLayer, restrictflag, visibility_flag)
DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits)
+DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totcagevert, cage_verts_num)
+DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totinfluence, influences_num)
+DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totvert, verts_num)
DNA_STRUCT_RENAME_ELEM(MovieClip, name, filepath)
+DNA_STRUCT_RENAME_ELEM(NodeCryptomatte, num_inputs, inputs_num)
DNA_STRUCT_RENAME_ELEM(Object, col, color)
DNA_STRUCT_RENAME_ELEM(Object, dup_group, instance_collection)
DNA_STRUCT_RENAME_ELEM(Object, dupfacesca, instance_faces_scale)
DNA_STRUCT_RENAME_ELEM(Object, restrictflag, visibility_flag)
DNA_STRUCT_RENAME_ELEM(Object, size, scale)
+DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_num)
+DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_group, instance_collection)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object)
DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights)
-DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame)
+DNA_STRUCT_RENAME_ELEM(ParticleSettings, ren_child_nbr, child_render_percent)
DNA_STRUCT_RENAME_ELEM(RenderData, bake_filter, bake_margin)
+DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame)
+DNA_STRUCT_RENAME_ELEM(SDefBind, numverts, verts_num)
+DNA_STRUCT_RENAME_ELEM(SDefVert, numbinds, binds_num)
DNA_STRUCT_RENAME_ELEM(SpaceSeq, overlay_type, overlay_frame_type)
-DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, num_bind_verts)
+DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, num_mesh_verts, mesh_verts_num)
+DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numpoly, polys_num)
+DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, bind_verts_num)
+DNA_STRUCT_RENAME_ELEM(SurfaceModifierData, numverts, verts_num)
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(UVProjectModifierData, num_projectors, projectors_num)
DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist)
DNA_STRUCT_RENAME_ELEM(VFont, name, filepath)
DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end)
diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c
index 8c86ef69ebd..bc2584fe57a 100644
--- a/source/blender/makesdna/intern/dna_utils.c
+++ b/source/blender/makesdna/intern/dna_utils.c
@@ -308,3 +308,21 @@ const char *DNA_struct_rename_legacy_hack_alias_from_static(const char *name)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Internal helpers for C++
+ * \{ */
+
+void _DNA_internal_memcpy(void *dst, const void *src, size_t size);
+void _DNA_internal_memcpy(void *dst, const void *src, const size_t size)
+{
+ memcpy(dst, src, size);
+}
+
+void _DNA_internal_memzero(void *dst, size_t size);
+void _DNA_internal_memzero(void *dst, const size_t size)
+{
+ memset(dst, 0, size);
+}
+
+/** \} */
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 0d2f265a9b5..12ec7262906 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -620,6 +620,7 @@ static int preprocess_include(char *maindata, const int maindata_len)
int newlen = 0;
comment = 0;
a = maindata_len;
+ bool skip_until_closing_brace = false;
while (a--) {
if (cp[0] == '/' && cp[1] == '*') {
@@ -646,6 +647,17 @@ static int preprocess_include(char *maindata, const int maindata_len)
a -= 13;
cp += 13;
}
+ else if (match_identifier(cp, "DNA_DEFINE_CXX_METHODS")) {
+ /* single values are skipped already, so decrement 1 less */
+ a -= 21;
+ cp += 21;
+ skip_until_closing_brace = true;
+ }
+ else if (skip_until_closing_brace) {
+ if (cp[0] == ')') {
+ skip_until_closing_brace = false;
+ }
+ }
else {
md[0] = cp[0];
md++;
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 4e3a4aae727..9980545c19d 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -236,6 +236,10 @@ if(WITH_IMAGE_HDR)
add_definitions(-DWITH_HDR)
endif()
+if(WITH_IMAGE_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
+
if(WITH_AUDASPACE)
add_definitions(-DWITH_AUDASPACE)
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index a9725da7841..82d90a5c54b 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -137,7 +137,11 @@ const struct IDFilterEnumPropertyItem rna_enum_id_type_filter_items[] = {
ICON_OUTLINER_COLLECTION,
"Collections",
"Show Collection data-blocks"},
- {FILTER_ID_CV, "filter_hair", ICON_CURVES_DATA, "Hairs", "Show/hide Hair data-blocks"},
+ {FILTER_ID_CV,
+ "filter_curves",
+ ICON_CURVES_DATA,
+ "Hair Curves",
+ "Show/hide Curves data-blocks"},
{FILTER_ID_IM, "filter_image", ICON_IMAGE_DATA, "Images", "Show Image data-blocks"},
{FILTER_ID_LA, "filter_light", ICON_LIGHT_DATA, "Lights", "Show Light data-blocks"},
{FILTER_ID_LP,
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index c86a852b0ea..b2b6bdbcffc 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -1355,7 +1355,8 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
/* Smoothing factor for new strokes */
prop = RNA_def_property(srna, "pen_smooth_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "draw_smoothfac");
- RNA_def_property_range(prop, 0.0, 2.0f);
+ RNA_def_property_range(prop, 0.0, 2.0);
+ RNA_def_property_ui_range(prop, 0.0, 1.0, 10, 3);
RNA_def_property_ui_text(
prop,
"Smooth",
@@ -1366,7 +1367,7 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
/* Iterations of the Smoothing factor */
prop = RNA_def_property(srna, "pen_smooth_steps", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "draw_smoothlvl");
- RNA_def_property_range(prop, 1, 3);
+ RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop, "Iterations", "Number of times to smooth newly created strokes");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index 33c0b29f6d0..81103f4fe49 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -79,6 +79,11 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = {
ICON_MOD_DASH,
"Dot Dash",
"Generate dot-dash styled strokes"},
+ {eGpencilModifierType_Envelope,
+ "GP_ENVELOPE",
+ ICON_MOD_SKIN,
+ "Envelope",
+ "Create an envelope shape"},
{eGpencilModifierType_Length,
"GP_LENGTH",
ICON_MOD_LENGTH,
@@ -208,6 +213,25 @@ static const EnumPropertyItem gpencil_length_mode_items[] = {
{GP_LENGTH_ABSOLUTE, "ABSOLUTE", 0, "Absolute", "Length in geometry space"},
{0, NULL, 0, NULL, NULL},
};
+
+static const EnumPropertyItem gpencil_envelope_mode_items[] = {
+ {GP_ENVELOPE_DEFORM,
+ "DEFORM",
+ 0,
+ "Deform",
+ "Deform the stroke to best match the envelope shape"},
+ {GP_ENVELOPE_SEGMENTS,
+ "SEGMENTS",
+ 0,
+ "Segments",
+ "Add segments to create the envelope. Keep the original stroke"},
+ {GP_ENVELOPE_FILLS,
+ "FILLS",
+ 0,
+ "Fills",
+ "Add fill segments to create the envelope. Don't keep the original stroke"},
+ {0, NULL, 0, NULL, NULL},
+};
#endif
#ifdef RNA_RUNTIME
@@ -279,6 +303,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr)
return &RNA_LineartGpencilModifier;
case eGpencilModifierType_Dash:
return &RNA_DashGpencilModifierData;
+ case eGpencilModifierType_Envelope:
+ return &RNA_EnvelopeGpencilModifier;
/* Default */
case eGpencilModifierType_None:
case NUM_GREASEPENCIL_MODIFIER_TYPES:
@@ -355,6 +381,7 @@ RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, target_vgname);
RNA_GP_MOD_VGROUP_NAME_SET(WeightAngle, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Lineart, vgname);
RNA_GP_MOD_VGROUP_NAME_SET(Shrinkwrap, vgname);
+RNA_GP_MOD_VGROUP_NAME_SET(Envelope, vgname);
# undef RNA_GP_MOD_VGROUP_NAME_SET
@@ -775,6 +802,16 @@ static void rna_ShrinkwrapGpencilModifier_face_cull_set(struct PointerRNA *ptr,
swm->shrink_opts = (swm->shrink_opts & ~MOD_SHRINKWRAP_CULL_TARGET_MASK) | value;
}
+static void rna_EnvelopeGpencilModifier_material_set(PointerRNA *ptr,
+ PointerRNA value,
+ struct ReportList *reports)
+{
+ EnvelopeGpencilModifierData *emd = (EnvelopeGpencilModifierData *)ptr->data;
+ Material **ma_target = &emd->material;
+
+ rna_GpencilModifier_material_set(ptr, value, ma_target, reports);
+}
+
#else
static void rna_def_modifier_gpencilnoise(BlenderRNA *brna)
@@ -989,11 +1026,16 @@ static void rna_def_modifier_gpencilsmooth(BlenderRNA *brna)
prop = RNA_def_property(srna, "step", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "step");
- RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_range(prop, 1, 1000);
RNA_def_property_ui_text(
prop, "Step", "Number of times to apply smooth (high numbers can reduce fps)");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+ prop = RNA_def_property(srna, "use_keep_shape", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_KEEP_SHAPE);
+ RNA_def_property_ui_text(prop, "Keep Shape", "Smooth the details, but keep the overall shape");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SMOOTH_INVERT_LAYER);
RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
@@ -3676,7 +3718,7 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "gap", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 1, INT16_MAX);
+ RNA_def_property_range(prop, 0, INT16_MAX);
RNA_def_property_ui_text(prop, "Gap", "The number of points skipped after this segment");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
@@ -3701,6 +3743,11 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna)
"Use this index on generated segment. -1 means using the existing material");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+ prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_USE_CYCLIC);
+ RNA_def_property_ui_text(prop, "Use Cyclic", "Enable cyclic on individual stroke dashes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
srna = RNA_def_struct(brna, "DashGpencilModifierData", "GpencilModifier");
RNA_def_struct_ui_text(srna, "Dash Modifier", "Create dot-dash effect for strokes");
RNA_def_struct_sdna(srna, "DashGpencilModifierData");
@@ -3752,17 +3799,17 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_LAYER);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_LAYER);
RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_MATERIAL);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_MATERIAL);
RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_PASS);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_PASS);
RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
@@ -3773,7 +3820,7 @@ static void rna_def_modifier_gpencildash(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LENGTH_INVERT_LAYERPASS);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DASH_INVERT_LAYERPASS);
RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
@@ -3968,6 +4015,112 @@ static void rna_def_modifier_gpencilshrinkwrap(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+static void rna_def_modifier_gpencilenvelope(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "EnvelopeGpencilModifier", "GpencilModifier");
+ RNA_def_struct_ui_text(srna, "Envelope Modifier", "Envelope stroke effect modifier");
+ RNA_def_struct_sdna(srna, "EnvelopeGpencilModifierData");
+ RNA_def_struct_ui_icon(srna, ICON_MOD_SKIN);
+
+ RNA_define_lib_overridable(true);
+
+ prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "layername");
+ RNA_def_property_ui_text(prop, "Layer", "Layer name");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_pointer_funcs(prop,
+ NULL,
+ "rna_EnvelopeGpencilModifier_material_set",
+ NULL,
+ "rna_GpencilModifier_material_poll");
+ RNA_def_property_ui_text(prop, "Material", "Material used for filtering effect");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "vertex_group", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "vgname");
+ RNA_def_property_ui_text(prop, "Vertex Group", "Vertex group name for modulating the deform");
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_EnvelopeGpencilModifier_vgname_set");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "pass_index");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "spread", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "spread");
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_text(
+ prop, "Spread Length", "The number of points to skip to create straight segments");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_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, gpencil_envelope_mode_items);
+ RNA_def_property_ui_text(prop, "Mode", "Algorithm to use for generating the envelope");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "mat_nr", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "mat_nr");
+ RNA_def_property_range(prop, -1, INT16_MAX);
+ RNA_def_property_ui_text(prop, "Material Index", "The material to use for the new strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "thickness", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "thickness");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Thickness", "Multiplier for the thickness of the new strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "strength");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0, 1, 10, 3);
+ RNA_def_property_ui_text(prop, "Strength", "Multiplier for the strength of the new strokes");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_LAYER);
+ RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_materials", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_MATERIAL);
+ RNA_def_property_ui_text(prop, "Inverse Materials", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_material_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_PASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_vertex", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_VGROUP);
+ RNA_def_property_ui_text(prop, "Inverse VertexGroup", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "layer_pass", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "layer_pass");
+ RNA_def_property_range(prop, 0, 100);
+ RNA_def_property_ui_text(prop, "Pass", "Layer pass index");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ prop = RNA_def_property(srna, "invert_layer_pass", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_ENVELOPE_INVERT_LAYERPASS);
+ RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
+ RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
+
+ RNA_define_lib_overridable(false);
+}
+
void RNA_def_greasepencil_modifier(BlenderRNA *brna)
{
StructRNA *srna;
@@ -4058,6 +4211,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna)
rna_def_modifier_gpencillength(brna);
rna_def_modifier_gpencildash(brna);
rna_def_modifier_gpencilshrinkwrap(brna);
+ rna_def_modifier_gpencilenvelope(brna);
}
#endif
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 55d365f9827..0b188b2b3db 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -102,14 +102,14 @@ static void rna_Image_save(Image *image, Main *bmain, bContext *C, ReportList *r
ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
if (ibuf) {
- char filename[FILE_MAX];
- BLI_strncpy(filename, image->filepath, sizeof(filename));
- BLI_path_abs(filename, ID_BLEND_PATH(bmain, &image->id));
+ char filepath[FILE_MAX];
+ BLI_strncpy(filepath, image->filepath, sizeof(filepath));
+ BLI_path_abs(filepath, ID_BLEND_PATH(bmain, &image->id));
/* NOTE: we purposefully ignore packed files here,
* developers need to explicitly write them via 'packed_files' */
- if (IMB_saveiff(ibuf, filename, ibuf->flags)) {
+ if (IMB_saveiff(ibuf, filepath, ibuf->flags)) {
image->type = IMA_TYPE_IMAGE;
if (image->source == IMA_SRC_GENERATED) {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 0bea5172d89..bd5960ce7d8 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -688,7 +688,7 @@ static void rna_UVProject_projectors_begin(CollectionPropertyIterator *iter, Poi
{
UVProjectModifierData *uvp = (UVProjectModifierData *)ptr->data;
rna_iterator_array_begin(
- iter, (void *)uvp->projectors, sizeof(Object *), uvp->num_projectors, 0, NULL);
+ iter, (void *)uvp->projectors, sizeof(Object *), uvp->projectors_num, 0, NULL);
}
static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
@@ -950,15 +950,15 @@ static int rna_HookModifier_vertex_indices_get_length(PointerRNA *ptr,
int length[RNA_MAX_ARRAY_DIMENSION])
{
HookModifierData *hmd = ptr->data;
- int totindex = hmd->indexar ? hmd->totindex : 0;
- return (length[0] = totindex);
+ int indexar_num = hmd->indexar ? hmd->indexar_num : 0;
+ return (length[0] = indexar_num);
}
static void rna_HookModifier_vertex_indices_get(PointerRNA *ptr, int *values)
{
HookModifierData *hmd = ptr->data;
if (hmd->indexar != NULL) {
- memcpy(values, hmd->indexar, sizeof(int) * hmd->totindex);
+ memcpy(values, hmd->indexar, sizeof(int) * hmd->indexar_num);
}
}
@@ -969,7 +969,7 @@ static void rna_HookModifier_vertex_indices_set(HookModifierData *hmd,
{
if (indices_len == 0) {
MEM_SAFE_FREE(hmd->indexar);
- hmd->totindex = 0;
+ hmd->indexar_num = 0;
}
else {
/* Reject negative indices. */
@@ -999,7 +999,7 @@ static void rna_HookModifier_vertex_indices_set(HookModifierData *hmd,
/* Success - save the new array. */
MEM_SAFE_FREE(hmd->indexar);
hmd->indexar = buffer;
- hmd->totindex = indices_len;
+ hmd->indexar_num = indices_len;
}
}
@@ -1075,7 +1075,7 @@ static void rna_MultiresModifier_filepath_get(PointerRNA *ptr, char *value)
Object *ob = (Object *)ptr->owner_id;
CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external;
- BLI_strncpy(value, (external) ? external->filename : "", sizeof(external->filename));
+ BLI_strncpy(value, (external) ? external->filepath : "", sizeof(external->filepath));
}
static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value)
@@ -1083,8 +1083,8 @@ static void rna_MultiresModifier_filepath_set(PointerRNA *ptr, const char *value
Object *ob = (Object *)ptr->owner_id;
CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external;
- if (external && !STREQ(external->filename, value)) {
- BLI_strncpy(external->filename, value, sizeof(external->filename));
+ if (external && !STREQ(external->filepath, value)) {
+ BLI_strncpy(external->filepath, value, sizeof(external->filepath));
multires_force_external_reload(ob);
}
}
@@ -1094,7 +1094,7 @@ static int rna_MultiresModifier_filepath_length(PointerRNA *ptr)
Object *ob = (Object *)ptr->owner_id;
CustomDataExternal *external = ((Mesh *)ob->data)->ldata.external;
- return strlen((external) ? external->filename : "");
+ return strlen((external) ? external->filepath : "");
}
static int rna_ShrinkwrapModifier_face_cull_get(PointerRNA *ptr)
@@ -1149,8 +1149,8 @@ static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value)
UVProjectModifierData *md = (UVProjectModifierData *)ptr->data;
int a;
- md->num_projectors = CLAMPIS(value, 1, MOD_UVPROJECT_MAXPROJECTORS);
- for (a = md->num_projectors; a < MOD_UVPROJECT_MAXPROJECTORS; a++) {
+ md->projectors_num = CLAMPIS(value, 1, MOD_UVPROJECT_MAXPROJECTORS);
+ for (a = md->projectors_num; a < MOD_UVPROJECT_MAXPROJECTORS; a++) {
md->projectors[a] = NULL;
}
}
@@ -3133,7 +3133,7 @@ static void rna_def_modifier_uvproject(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "projector_count", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "num_projectors");
+ RNA_def_property_int_sdna(prop, NULL, "projectors_num");
RNA_def_property_ui_text(prop, "Number of Projectors", "Number of projectors to use");
RNA_def_property_int_funcs(prop, NULL, "rna_UVProjectModifier_num_projectors_set", NULL);
RNA_def_property_range(prop, 1, MOD_UVPROJECT_MAXPROJECTORS);
@@ -4110,7 +4110,7 @@ static void rna_def_modifier_bevel(BlenderRNA *brna)
prop = RNA_def_property(srna, "segments", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "res");
- RNA_def_property_range(prop, 1, 100);
+ RNA_def_property_range(prop, 1, 1000);
RNA_def_property_ui_text(prop, "Segments", "Number of segments for round edges/verts");
RNA_def_property_update(prop, 0, "rna_BevelModifier_update_segments");
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 2770255802d..03f800d14d1 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -3139,15 +3139,19 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Particle_redo");
/* children */
+
+ /* NOTE(@campbellbarton): name is not following conventions: `nbr`.
+ * Could be changed next major version. */
prop = RNA_def_property(srna, "child_nbr", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "child_nbr"); /* Optional if prop names are the same. */
+ RNA_def_property_int_sdna(
+ prop, NULL, "child_percent"); /* Optional if prop names are the same. */
RNA_def_property_range(prop, 0, 100000);
RNA_def_property_ui_range(prop, 0, 1000, 1, -1);
RNA_def_property_ui_text(prop, "Children Per Parent", "Number of children per parent");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "rendered_child_count", PROP_INT, PROP_NONE);
- RNA_def_property_int_sdna(prop, NULL, "ren_child_nbr");
+ RNA_def_property_int_sdna(prop, NULL, "child_render_percent");
RNA_def_property_range(prop, 0, 100000);
RNA_def_property_ui_range(prop, 0, 10000, 1, -1);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 9400e34d193..abaee9ddfc3 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -330,6 +330,13 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = {
# define R_IMF_ENUM_TIFF
#endif
+#ifdef WITH_WEBP
+# define R_IMF_ENUM_WEBP \
+ {R_IMF_IMTYPE_WEBP, "WEBP", ICON_FILE_IMAGE, "WebP", "Output image in WebP format"},
+#else
+# define R_IMF_ENUM_WEBP
+#endif
+
#define IMAGE_TYPE_ITEMS_IMAGE_ONLY \
R_IMF_ENUM_BMP \
/* DDS save not supported yet R_IMF_ENUM_DDS */ \
@@ -340,7 +347,7 @@ const EnumPropertyItem rna_enum_curve_fit_method_items[] = {
R_IMF_ENUM_TAGA \
R_IMF_ENUM_TAGA_RAW{0, "", 0, " ", NULL}, \
R_IMF_ENUM_CINEON R_IMF_ENUM_DPX R_IMF_ENUM_EXR_MULTILAYER R_IMF_ENUM_EXR R_IMF_ENUM_HDR \
- R_IMF_ENUM_TIFF
+ R_IMF_ENUM_TIFF R_IMF_ENUM_WEBP
#ifdef RNA_RUNTIME
static const EnumPropertyItem image_only_type_items[] = {
@@ -6213,7 +6220,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "hair_subdiv", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 3);
- RNA_def_property_ui_text(prop, "Additional Subdivision", "Additional subdivision along the hair");
+ RNA_def_property_ui_text(
+ prop, "Additional Subdivision", "Additional subdivision along the hair");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
/* Performance */
diff --git a/source/blender/makesrna/intern/rna_shader_fx.c b/source/blender/makesrna/intern/rna_shader_fx.c
index ae7772fcb62..cefa445740d 100644
--- a/source/blender/makesrna/intern/rna_shader_fx.c
+++ b/source/blender/makesrna/intern/rna_shader_fx.c
@@ -524,7 +524,6 @@ static void rna_def_shader_fx_glow(BlenderRNA *brna)
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_SHADERFX, "rna_ShaderFx_update");
prop = RNA_def_property(srna, "select_color", PROP_FLOAT, PROP_COLOR);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 2344aa42838..3839b3ba6a4 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -3773,13 +3773,6 @@ static void rna_def_space_outliner(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Filter by Type", "Data-block type to show");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
- prop = RNA_def_property(srna, "use_filter_lib_override", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "filter", SO_FILTER_NO_LIB_OVERRIDE);
- RNA_def_property_ui_text(prop,
- "Show Library Overrides",
- "For libraries with overrides created, show the overridden values");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
prop = RNA_def_property(srna, "use_filter_lib_override_system", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filter", SO_FILTER_SHOW_SYSTEM_OVERRIDES);
RNA_def_property_ui_text(
diff --git a/source/blender/makesrna/intern/rna_text.c b/source/blender/makesrna/intern/rna_text.c
index 3d2df5b7411..e9c67d71ceb 100644
--- a/source/blender/makesrna/intern/rna_text.c
+++ b/source/blender/makesrna/intern/rna_text.c
@@ -25,7 +25,7 @@
#ifdef RNA_RUNTIME
-static void rna_Text_filename_get(PointerRNA *ptr, char *value)
+static void rna_Text_filepath_get(PointerRNA *ptr, char *value)
{
Text *text = (Text *)ptr->data;
@@ -37,13 +37,13 @@ static void rna_Text_filename_get(PointerRNA *ptr, char *value)
}
}
-static int rna_Text_filename_length(PointerRNA *ptr)
+static int rna_Text_filepath_length(PointerRNA *ptr)
{
Text *text = (Text *)ptr->data;
return (text->filepath) ? strlen(text->filepath) : 0;
}
-static void rna_Text_filename_set(PointerRNA *ptr, const char *value)
+static void rna_Text_filepath_set(PointerRNA *ptr, const char *value)
{
Text *text = (Text *)ptr->data;
@@ -204,7 +204,7 @@ static void rna_def_text(BlenderRNA *brna)
prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(
- prop, "rna_Text_filename_get", "rna_Text_filename_length", "rna_Text_filename_set");
+ prop, "rna_Text_filepath_get", "rna_Text_filepath_length", "rna_Text_filepath_set");
RNA_def_property_ui_text(prop, "File Path", "Filename of the text file");
prop = RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index a0d53701e26..06a5df5ad41 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -5278,10 +5278,10 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Duplicate GPencil", "Causes grease pencil data to be duplicated with the object");
- prop = RNA_def_property(srna, "use_duplicate_hair", PROP_BOOLEAN, PROP_NONE);
+ prop = RNA_def_property(srna, "use_duplicate_curves", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_CURVES);
RNA_def_property_ui_text(
- prop, "Duplicate Hair", "Causes hair data to be duplicated with the object");
+ prop, "Duplicate Curves", "Causes curves data to be duplicated with the object");
prop = RNA_def_property(srna, "use_duplicate_pointcloud", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_POINTCLOUD);
@@ -6435,6 +6435,12 @@ static void rna_def_userdef_experimental(BlenderRNA *brna)
"Named Attribute Nodes",
"Enable named attribute nodes in the geometry nodes add menu");
+ prop = RNA_def_property(srna, "use_select_nearest_on_first_click", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_select_nearest_on_first_click", 1);
+ RNA_def_property_ui_text(prop,
+ "Object Select Nearest on First Click",
+ "When enabled, always select the front-most object on the first click");
+
prop = RNA_def_property(srna, "enable_eevee_next", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "enable_eevee_next", 1);
RNA_def_property_ui_text(prop, "EEVEE Next", "Enable the new EEVEE codebase, requires restart");
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 5d37ac79fa6..f6e8a26f0e1 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -132,7 +132,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
@@ -142,7 +142,7 @@ static void deformVerts(ModifierData *md,
ctx->object,
vertexCos,
NULL,
- numVerts,
+ verts_num,
amd->deformflag,
amd->vert_coords_prev,
amd->defgrp_name,
@@ -157,10 +157,10 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
if (mesh != NULL) {
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}
@@ -172,7 +172,7 @@ static void deformVertsEM(ModifierData *md,
ctx->object,
vertexCos,
NULL,
- numVerts,
+ verts_num,
amd->deformflag,
amd->vert_coords_prev,
amd->defgrp_name,
@@ -188,7 +188,7 @@ static void deformMatricesEM(ModifierData *md,
Mesh *UNUSED(mesh),
float (*vertexCos)[3],
float (*defMats)[3][3],
- int numVerts)
+ int verts_num)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
@@ -196,7 +196,7 @@ static void deformMatricesEM(ModifierData *md,
ctx->object,
vertexCos,
defMats,
- numVerts,
+ verts_num,
amd->deformflag,
NULL,
amd->defgrp_name,
@@ -208,16 +208,17 @@ static void deformMatrices(ModifierData *md,
Mesh *mesh,
float (*vertexCos)[3],
float (*defMats)[3][3],
- int numVerts)
+ int verts_num)
{
ArmatureModifierData *amd = (ArmatureModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
BKE_armature_deform_coords_with_mesh(amd->object,
ctx->object,
vertexCos,
defMats,
- numVerts,
+ verts_num,
amd->deformflag,
NULL,
amd->defgrp_name,
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index b237f952287..758858c8b1d 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -139,17 +139,17 @@ static void svert_from_mvert(SortVertsElem *sv,
/**
* Take as inputs two sets of verts, to be processed for detection of doubles and mapping.
- * Each set of verts is defined by its start within mverts array and its num_verts;
+ * Each set of verts is defined by its start within mverts array and its verts_num;
* It builds a mapping for all vertices within source,
* to vertices within target, or -1 if no double found.
- * The int doubles_map[num_verts_source] array must have been allocated by caller.
+ * The `int doubles_map[verts_source_num]` array must have been allocated by caller.
*/
static void dm_mvert_map_doubles(int *doubles_map,
const MVert *mverts,
const int target_start,
- const int target_num_verts,
+ const int target_verts_num,
const int source_start,
- const int source_num_verts,
+ const int source_verts_num,
const float dist)
{
const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */
@@ -158,12 +158,12 @@ static void dm_mvert_map_doubles(int *doubles_map,
SortVertsElem *sve_source, *sve_target, *sve_target_low_bound;
bool target_scan_completed;
- target_end = target_start + target_num_verts;
- source_end = source_start + source_num_verts;
+ target_end = target_start + target_verts_num;
+ source_end = source_start + source_verts_num;
/* build array of MVerts to be tested for merging */
- sorted_verts_target = MEM_malloc_arrayN(target_num_verts, sizeof(SortVertsElem), __func__);
- sorted_verts_source = MEM_malloc_arrayN(source_num_verts, sizeof(SortVertsElem), __func__);
+ sorted_verts_target = MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__);
+ sorted_verts_source = MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__);
/* Copy target vertices index and cos into SortVertsElem array */
svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end);
@@ -172,8 +172,8 @@ static void dm_mvert_map_doubles(int *doubles_map,
svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end);
/* sort arrays according to sum of vertex coordinates (sumco) */
- qsort(sorted_verts_target, target_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
- qsort(sorted_verts_source, source_num_verts, sizeof(SortVertsElem), svert_sum_cmp);
+ qsort(sorted_verts_target, target_verts_num, sizeof(SortVertsElem), svert_sum_cmp);
+ qsort(sorted_verts_source, source_verts_num, sizeof(SortVertsElem), svert_sum_cmp);
sve_target_low_bound = sorted_verts_target;
i_target_low_bound = 0;
@@ -181,7 +181,7 @@ static void dm_mvert_map_doubles(int *doubles_map,
/* Scan source vertices, in #SortVertsElem sorted array,
* all the while maintaining the lower bound of possible doubles in target vertices. */
- for (i_source = 0, sve_source = sorted_verts_source; i_source < source_num_verts;
+ for (i_source = 0, sve_source = sorted_verts_source; i_source < source_verts_num;
i_source++, sve_source++) {
int best_target_vertex = -1;
float best_dist_sq = dist * dist;
@@ -202,13 +202,13 @@ static void dm_mvert_map_doubles(int *doubles_map,
/* Skip all target vertices that are more than dist3 lower in terms of sumco */
/* and advance the overall lower bound, applicable to all remaining vertices as well. */
- while ((i_target_low_bound < target_num_verts) &&
+ while ((i_target_low_bound < target_verts_num) &&
(sve_target_low_bound->sum_co < sve_source_sumco - dist3)) {
i_target_low_bound++;
sve_target_low_bound++;
}
/* If end of target list reached, then no more possible doubles */
- if (i_target_low_bound >= target_num_verts) {
+ if (i_target_low_bound >= target_verts_num) {
doubles_map[sve_source->vertex_num] = -1;
target_scan_completed = true;
continue;
@@ -221,7 +221,7 @@ static void dm_mvert_map_doubles(int *doubles_map,
/* i_target will scan vertices in the
* [v_source_sumco - dist3; v_source_sumco + dist3] range */
- while ((i_target < target_num_verts) && (sve_target->sum_co <= sve_source_sumco + dist3)) {
+ while ((i_target < target_verts_num) && (sve_target->sum_co <= sve_source_sumco + dist3)) {
/* Testing distance for candidate double in target */
/* v_target is within dist3 of v_source in terms of sumco; check real distance */
float dist_sq;
@@ -478,7 +478,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
}
/* About 67 million vertices max seems a decent limit for now. */
- const size_t max_num_vertices = 1 << 26;
+ const size_t max_vertices_num = 1 << 26;
/* calculate the maximum number of copies which will fit within the
* prescribed length */
@@ -496,7 +496,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
* vertices.
*/
if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts +
- (size_t)end_cap_nverts) > max_num_vertices) {
+ (size_t)end_cap_nverts) > max_vertices_num) {
count = 1;
offset_is_too_small = true;
}
@@ -518,7 +518,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
* vertices.
*/
else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts +
- (size_t)end_cap_nverts) > max_num_vertices) {
+ (size_t)end_cap_nverts) > max_vertices_num) {
count = 1;
BKE_modifier_set_error(ctx->object,
&amd->modifier,
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index cd77abfca50..d7baea7887d 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -58,7 +58,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
Mesh *result;
BuildModifierData *bmd = (BuildModifierData *)md;
int i, j, k;
- int numFaces_dst, numEdges_dst, numLoops_dst = 0;
+ int faces_dst_num, edges_dst_num, loops_dst_num = 0;
int *vertMap, *edgeMap, *faceMap;
float frac;
MPoly *mpoly_dst;
@@ -71,21 +71,21 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
/* maps edge indices in old mesh to indices in new mesh */
GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");
- const int numVert_src = mesh->totvert;
- const int numEdge_src = mesh->totedge;
- const int numPoly_src = mesh->totpoly;
+ const int vert_src_num = mesh->totvert;
+ const int edge_src_num = mesh->totedge;
+ const int poly_src_num = mesh->totpoly;
MPoly *mpoly_src = mesh->mpoly;
MLoop *mloop_src = mesh->mloop;
MEdge *medge_src = mesh->medge;
MVert *mvert_src = mesh->mvert;
- vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap");
- edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap");
- faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap");
+ vertMap = MEM_malloc_arrayN(vert_src_num, sizeof(*vertMap), "build modifier vertMap");
+ edgeMap = MEM_malloc_arrayN(edge_src_num, sizeof(*edgeMap), "build modifier edgeMap");
+ faceMap = MEM_malloc_arrayN(poly_src_num, sizeof(*faceMap), "build modifier faceMap");
- range_vn_i(vertMap, numVert_src, 0);
- range_vn_i(edgeMap, numEdge_src, 0);
- range_vn_i(faceMap, numPoly_src, 0);
+ range_vn_i(vertMap, vert_src_num, 0);
+ range_vn_i(edgeMap, edge_src_num, 0);
+ range_vn_i(faceMap, poly_src_num, 0);
struct Scene *scene = DEG_get_input_scene(ctx->depsgraph);
frac = (BKE_scene_ctime_get(scene) - bmd->start) / bmd->length;
@@ -94,17 +94,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
frac = 1.0f - frac;
}
- numFaces_dst = numPoly_src * frac;
- numEdges_dst = numEdge_src * frac;
+ faces_dst_num = poly_src_num * frac;
+ edges_dst_num = edge_src_num * frac;
/* if there's at least one face, build based on faces */
- if (numFaces_dst) {
+ if (faces_dst_num) {
MPoly *mpoly, *mp;
MLoop *ml, *mloop;
uintptr_t hash_num, hash_num_alt;
if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
- BLI_array_randomize(faceMap, sizeof(*faceMap), numPoly_src, bmd->seed);
+ BLI_array_randomize(faceMap, sizeof(*faceMap), poly_src_num, bmd->seed);
}
/* get the set of all vert indices that will be in the final mesh,
@@ -113,7 +113,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
mpoly = mpoly_src;
mloop = mloop_src;
hash_num = 0;
- for (i = 0; i < numFaces_dst; i++) {
+ for (i = 0; i < faces_dst_num; i++) {
mp = mpoly + faceMap[i];
ml = mloop + mp->loopstart;
@@ -125,7 +125,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
}
}
- numLoops_dst += mp->totloop;
+ loops_dst_num += mp->totloop;
}
BLI_assert(hash_num == BLI_ghash_len(vertHash));
@@ -134,7 +134,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
*/
hash_num = 0;
hash_num_alt = 0;
- for (i = 0; i < numEdge_src; i++, hash_num_alt++) {
+ for (i = 0; i < edge_src_num; i++, hash_num_alt++) {
MEdge *me = medge_src + i;
if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) &&
@@ -146,12 +146,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
}
BLI_assert(hash_num == BLI_ghash_len(edgeHash));
}
- else if (numEdges_dst) {
+ else if (edges_dst_num) {
MEdge *medge, *me;
uintptr_t hash_num;
if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
- BLI_array_randomize(edgeMap, sizeof(*edgeMap), numEdge_src, bmd->seed);
+ BLI_array_randomize(edgeMap, sizeof(*edgeMap), edge_src_num, bmd->seed);
}
/* get the set of all vert indices that will be in the final mesh,
@@ -160,7 +160,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
medge = medge_src;
hash_num = 0;
BLI_assert(hash_num == BLI_ghash_len(vertHash));
- for (i = 0; i < numEdges_dst; i++) {
+ for (i = 0; i < edges_dst_num; i++) {
void **val_p;
me = medge + edgeMap[i];
@@ -176,7 +176,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
BLI_assert(hash_num == BLI_ghash_len(vertHash));
/* get the set of edges that will be in the new mesh */
- for (i = 0; i < numEdges_dst; i++) {
+ for (i = 0; i < edges_dst_num; i++) {
j = BLI_ghash_len(edgeHash);
BLI_ghash_insert(edgeHash, POINTER_FROM_INT(j), POINTER_FROM_INT(edgeMap[i]));
@@ -184,23 +184,23 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
}
}
else {
- int numVerts = numVert_src * frac;
+ int verts_num = vert_src_num * frac;
if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
- BLI_array_randomize(vertMap, sizeof(*vertMap), numVert_src, bmd->seed);
+ BLI_array_randomize(vertMap, sizeof(*vertMap), vert_src_num, bmd->seed);
}
/* get the set of all vert indices that will be in the final mesh,
* mapped to the new indices
*/
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
BLI_ghash_insert(vertHash, POINTER_FROM_INT(vertMap[i]), POINTER_FROM_INT(i));
}
}
/* now we know the number of verts, edges and faces, we can create the mesh. */
result = BKE_mesh_new_nomain_from_template(
- mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst);
+ mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, loops_dst_num, faces_dst_num);
/* copy the vertices across */
GHASH_ITER (gh_iter, vertHash) {
@@ -237,7 +237,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
/* copy the faces across, remapping indices */
k = 0;
- for (i = 0; i < numFaces_dst; i++) {
+ for (i = 0; i < faces_dst_num; i++) {
MPoly *source;
MPoly *dest;
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index fb395631451..3916551bc90 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -96,7 +96,7 @@ static void sphere_do(CastModifierData *cmd,
Object *ob,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
MDeformVert *dvert = NULL;
const bool invert_vgroup = (cmd->flag & MOD_CAST_INVERT_VGROUP) != 0;
@@ -159,17 +159,17 @@ static void sphere_do(CastModifierData *cmd,
}
if (len <= 0) {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
len += len_v3v3(center, vertexCos[i]);
}
- len /= numVerts;
+ len /= verts_num;
if (len == 0.0f) {
len = 10.0f;
}
}
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float tmp_co[3];
copy_v3_v3(tmp_co, vertexCos[i]);
@@ -237,7 +237,7 @@ static void cuboid_do(CastModifierData *cmd,
Object *ob,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
MDeformVert *dvert = NULL;
int defgrp_index;
@@ -312,13 +312,13 @@ static void cuboid_do(CastModifierData *cmd,
/* let the center of the ctrl_ob be part of the bound box: */
minmax_v3v3_v3(min, max, center);
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
sub_v3_v3v3(vec, vertexCos[i], center);
minmax_v3v3_v3(min, max, vec);
}
}
else {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
minmax_v3v3_v3(min, max, vertexCos[i]);
}
}
@@ -347,7 +347,7 @@ static void cuboid_do(CastModifierData *cmd,
bb[4][2] = bb[5][2] = bb[6][2] = bb[7][2] = max[2];
/* ready to apply the effect, one vertex at a time */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
int octant, coord;
float d[3], dmax, apex[3], fbb;
float tmp_co[3];
@@ -460,21 +460,21 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
CastModifierData *cmd = (CastModifierData *)md;
Mesh *mesh_src = NULL;
if (ctx->object->type == OB_MESH && cmd->defgrp_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
if (!ELEM(mesh_src, NULL, mesh)) {
@@ -487,17 +487,18 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
CastModifierData *cmd = (CastModifierData *)md;
Mesh *mesh_src = NULL;
if (cmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
}
if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
- BLI_assert(mesh->totvert == numVerts);
+ BLI_assert(mesh->totvert == verts_num);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -506,10 +507,10 @@ static void deformVertsEM(ModifierData *md,
}
if (cmd->type == MOD_CAST_TYPE_CUBOID) {
- cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ cuboid_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
else { /* MOD_CAST_TYPE_SPHERE or MOD_CAST_TYPE_CYLINDER */
- sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ sphere_do(cmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
}
if (!ELEM(mesh_src, NULL, mesh)) {
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 4bc79a9dd45..6389f420588 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -78,7 +78,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src;
ClothModifierData *clmd = (ClothModifierData *)md;
@@ -94,7 +94,7 @@ static void deformVerts(ModifierData *md,
}
if (mesh == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false, false);
}
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
@@ -118,7 +118,7 @@ static void deformVerts(ModifierData *md,
&mesh_src->vdata, CD_CLOTH_ORCO, CD_CALLOC, NULL, mesh_src->totvert);
}
- memcpy(layerorco, kb->data, sizeof(float[3]) * numVerts);
+ memcpy(layerorco, kb->data, sizeof(float[3]) * verts_num);
}
}
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 33a5934d2b0..9791b046e00 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -91,7 +91,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
CollisionModifierData *collmd = (CollisionModifierData *)md;
Mesh *mesh_src;
@@ -109,7 +109,7 @@ static void deformVerts(ModifierData *md,
}
if (mesh == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ob, NULL, NULL, NULL, verts_num, false, false);
}
else {
/* Not possible to use get_mesh() in this case as we'll modify its vertices
@@ -268,9 +268,9 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
collmd->xnew = newdataadr(fd, collmd->xnew);
collmd->mfaces = newdataadr(fd, collmd->mfaces);
- collmd->current_x = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_x");
- collmd->current_xnew = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_xnew");
- collmd->current_v = MEM_calloc_arrayN(collmd->numverts, sizeof(MVert), "current_v");
+ collmd->current_x = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_x");
+ collmd->current_xnew = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_xnew");
+ collmd->current_v = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_v");
#endif
collmd->x = NULL;
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index b61419eb663..52162eaacc5 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -111,13 +111,13 @@ static void requiredDataMask(Object *UNUSED(ob),
/* check individual weights for changes and cache values */
static void mesh_get_weights(MDeformVert *dvert,
const int defgrp_index,
- const uint numVerts,
+ const uint verts_num,
const bool use_invert_vgroup,
float *smooth_weights)
{
uint i;
- for (i = 0; i < numVerts; i++, dvert++) {
+ for (i = 0; i < verts_num; i++, dvert++) {
const float w = BKE_defvert_find_weight(dvert, defgrp_index);
if (use_invert_vgroup == false) {
@@ -170,25 +170,25 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
Mesh *mesh,
float (*vertexCos)[3],
- uint numVerts,
+ uint verts_num,
const float *smooth_weights,
uint iterations)
{
const float lambda = csmd->lambda;
uint i;
- const uint numEdges = (uint)mesh->totedge;
+ const uint edges_num = (uint)mesh->totedge;
const MEdge *edges = mesh->medge;
float *vertex_edge_count_div;
struct SmoothingData_Simple {
float delta[3];
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+ } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__);
- vertex_edge_count_div = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
+ vertex_edge_count_div = MEM_calloc_arrayN(verts_num, sizeof(float), __func__);
/* calculate as floats to avoid int->float conversion in #smooth_iter */
- for (i = 0; i < numEdges; i++) {
+ for (i = 0; i < edges_num; i++) {
vertex_edge_count_div[edges[i].v1] += 1.0f;
vertex_edge_count_div[edges[i].v2] += 1.0f;
}
@@ -196,14 +196,14 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
/* a little confusing, but we can include 'lambda' and smoothing weight
* here to avoid multiplying for every iteration */
if (smooth_weights == NULL) {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ?
(1.0f / vertex_edge_count_div[i]) :
1.0f);
}
}
else {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
vertex_edge_count_div[i] = smooth_weights[i] * lambda *
(vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) :
1.0f);
@@ -214,7 +214,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
/* Main Smoothing Loop */
while (iterations--) {
- for (i = 0; i < numEdges; i++) {
+ for (i = 0; i < edges_num; i++) {
struct SmoothingData_Simple *sd_v1;
struct SmoothingData_Simple *sd_v2;
float edge_dir[3];
@@ -228,7 +228,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
sub_v3_v3(sd_v2->delta, edge_dir);
}
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
struct SmoothingData_Simple *sd = &smooth_data[i];
madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]);
/* zero for the next iteration (saves memset on entire array) */
@@ -246,12 +246,12 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd,
static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
Mesh *mesh,
float (*vertexCos)[3],
- uint numVerts,
+ uint verts_num,
const float *smooth_weights,
uint iterations)
{
const float eps = FLT_EPSILON * 10.0f;
- const uint numEdges = (uint)mesh->totedge;
+ const uint edges_num = (uint)mesh->totedge;
/* NOTE: the way this smoothing method works, its approx half as strong as the simple-smooth,
* and 2.0 rarely spikes, double the value for consistent behavior. */
const float lambda = csmd->lambda * 2.0f;
@@ -262,11 +262,11 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
struct SmoothingData_Weighted {
float delta[3];
float edge_length_sum;
- } *smooth_data = MEM_calloc_arrayN(numVerts, sizeof(*smooth_data), __func__);
+ } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__);
/* calculate as floats to avoid int->float conversion in #smooth_iter */
- vertex_edge_count = MEM_calloc_arrayN(numVerts, sizeof(float), __func__);
- for (i = 0; i < numEdges; i++) {
+ vertex_edge_count = MEM_calloc_arrayN(verts_num, sizeof(float), __func__);
+ for (i = 0; i < edges_num; i++) {
vertex_edge_count[edges[i].v1] += 1.0f;
vertex_edge_count[edges[i].v2] += 1.0f;
}
@@ -275,7 +275,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
/* Main Smoothing Loop */
while (iterations--) {
- for (i = 0; i < numEdges; i++) {
+ for (i = 0; i < edges_num; i++) {
struct SmoothingData_Weighted *sd_v1;
struct SmoothingData_Weighted *sd_v2;
float edge_dir[3];
@@ -299,7 +299,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
if (smooth_weights == NULL) {
/* fast-path */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
struct SmoothingData_Weighted *sd = &smooth_data[i];
/* Divide by sum of all neighbor distances (weighted) and amount of neighbors,
* (mean average). */
@@ -320,7 +320,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
}
}
else {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
struct SmoothingData_Weighted *sd = &smooth_data[i];
const float div = sd->edge_length_sum * vertex_edge_count[i];
if (div > eps) {
@@ -340,18 +340,18 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd,
static void smooth_iter(CorrectiveSmoothModifierData *csmd,
Mesh *mesh,
float (*vertexCos)[3],
- uint numVerts,
+ uint verts_num,
const float *smooth_weights,
uint iterations)
{
switch (csmd->smooth_type) {
case MOD_CORRECTIVESMOOTH_SMOOTH_LENGTH_WEIGHT:
- smooth_iter__length_weight(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ smooth_iter__length_weight(csmd, mesh, vertexCos, verts_num, smooth_weights, iterations);
break;
/* case MOD_CORRECTIVESMOOTH_SMOOTH_SIMPLE: */
default:
- smooth_iter__simple(csmd, mesh, vertexCos, numVerts, smooth_weights, iterations);
+ smooth_iter__simple(csmd, mesh, vertexCos, verts_num, smooth_weights, iterations);
break;
}
}
@@ -361,23 +361,23 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd,
MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
- uint numVerts)
+ uint verts_num)
{
float *smooth_weights = NULL;
if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) {
- smooth_weights = MEM_malloc_arrayN(numVerts, sizeof(float), __func__);
+ smooth_weights = MEM_malloc_arrayN(verts_num, sizeof(float), __func__);
if (dvert) {
mesh_get_weights(dvert,
defgrp_index,
- numVerts,
+ verts_num,
(csmd->flag & MOD_CORRECTIVESMOOTH_INVERT_VGROUP) != 0,
smooth_weights);
}
else {
- copy_vn_fl(smooth_weights, (int)numVerts, 1.0f);
+ copy_vn_fl(smooth_weights, (int)verts_num, 1.0f);
}
if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) {
@@ -385,7 +385,7 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd,
}
}
- smooth_iter(csmd, mesh, vertexCos, numVerts, smooth_weights, (uint)csmd->repeat);
+ smooth_iter(csmd, mesh, vertexCos, verts_num, smooth_weights, (uint)csmd->repeat);
if (smooth_weights) {
MEM_freeN(smooth_weights);
@@ -522,29 +522,29 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
MDeformVert *dvert,
const int defgrp_index,
const float (*rest_coords)[3],
- uint numVerts)
+ uint verts_num)
{
float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
float(*tangent_spaces)[3][3];
uint i;
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__);
- if (csmd->delta_cache.totverts != numVerts) {
+ if (csmd->delta_cache.totverts != verts_num) {
MEM_SAFE_FREE(csmd->delta_cache.deltas);
}
/* allocate deltas if they have not yet been allocated, otherwise we will just write over them */
if (!csmd->delta_cache.deltas) {
- csmd->delta_cache.totverts = numVerts;
- csmd->delta_cache.deltas = MEM_malloc_arrayN(numVerts, sizeof(float[3]), __func__);
+ csmd->delta_cache.totverts = verts_num;
+ csmd->delta_cache.deltas = MEM_malloc_arrayN(verts_num, sizeof(float[3]), __func__);
}
- smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, numVerts);
+ smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num);
calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float imat[3][3], delta[3];
#ifdef USE_TANGENT_CALC_INLINE
@@ -567,7 +567,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
Object *ob,
Mesh *mesh,
float (*vertexCos)[3],
- uint numVerts,
+ uint verts_num,
struct BMEditMesh *em)
{
CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md;
@@ -591,7 +591,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (DEG_is_active(depsgraph)) {
BLI_assert(csmd->bind_coords == NULL);
csmd->bind_coords = MEM_dupallocN(vertexCos);
- csmd->bind_coords_num = numVerts;
+ csmd->bind_coords_num = verts_num;
BLI_assert(csmd->bind_coords != NULL);
/* Copy bound data to the original modifier. */
CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *)
@@ -605,7 +605,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
}
if (UNLIKELY(use_only_smooth)) {
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, verts_num);
return;
}
@@ -616,9 +616,9 @@ static void correctivesmooth_modifier_do(ModifierData *md,
/* If the number of verts has changed, the bind is invalid, so we do nothing */
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
- if (csmd->bind_coords_num != numVerts) {
+ if (csmd->bind_coords_num != verts_num) {
BKE_modifier_set_error(
- ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts);
+ ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, verts_num);
goto error;
}
}
@@ -631,16 +631,16 @@ static void correctivesmooth_modifier_do(ModifierData *md,
else {
uint me_numVerts = (uint)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert);
- if (me_numVerts != numVerts) {
+ if (me_numVerts != verts_num) {
BKE_modifier_set_error(
- ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts);
+ ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, verts_num);
goto error;
}
}
}
/* check to see if our deltas are still valid */
- if (!csmd->delta_cache.deltas || (csmd->delta_cache.totverts != numVerts) ||
+ if (!csmd->delta_cache.deltas || (csmd->delta_cache.totverts != verts_num) ||
force_delta_cache_update) {
const float(*rest_coords)[3];
bool is_rest_coords_alloc = false;
@@ -649,7 +649,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
/* caller needs to do sanity check here */
- csmd->bind_coords_num = numVerts;
+ csmd->bind_coords_num = verts_num;
rest_coords = csmd->bind_coords;
}
else {
@@ -657,7 +657,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
rest_coords = em ? BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts) :
BKE_mesh_vert_coords_alloc(ob->data, &me_numVerts);
- BLI_assert((uint)me_numVerts == numVerts);
+ BLI_assert((uint)me_numVerts == verts_num);
is_rest_coords_alloc = true;
}
@@ -665,7 +665,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
TIMEIT_START(corrective_smooth_deltas);
#endif
- calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, numVerts);
+ calc_deltas(csmd, mesh, dvert, defgrp_index, rest_coords, verts_num);
#ifdef DEBUG_TIME
TIMEIT_END(corrective_smooth_deltas);
@@ -677,7 +677,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) {
/* this could be a check, but at this point it _must_ be valid */
- BLI_assert(csmd->bind_coords_num == numVerts && csmd->delta_cache.deltas);
+ BLI_assert(csmd->bind_coords_num == verts_num && csmd->delta_cache.deltas);
}
#ifdef DEBUG_TIME
@@ -685,7 +685,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
#endif
/* do the actual delta mush */
- smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, numVerts);
+ smooth_verts(csmd, mesh, dvert, defgrp_index, vertexCos, verts_num);
{
uint i;
@@ -693,11 +693,11 @@ static void correctivesmooth_modifier_do(ModifierData *md,
float(*tangent_spaces)[3][3];
const float scale = csmd->scale;
/* calloc, since values are accumulated */
- tangent_spaces = MEM_calloc_arrayN(numVerts, sizeof(float[3][3]), __func__);
+ tangent_spaces = MEM_calloc_arrayN(verts_num, sizeof(float[3][3]), __func__);
calc_tangent_spaces(mesh, vertexCos, tangent_spaces);
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float delta[3];
#ifdef USE_TANGENT_CALC_INLINE
@@ -727,12 +727,13 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
correctivesmooth_modifier_do(
- md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, NULL);
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, NULL);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -744,10 +745,10 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, NULL, numVerts, false, false);
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(Campbell): use edit-mode data only (remove this line). */
if (mesh_src != NULL) {
@@ -755,7 +756,7 @@ static void deformVertsEM(ModifierData *md,
}
correctivesmooth_modifier_do(
- md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)numVerts, editData);
+ md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, editData);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 5b22b933823..a82b999f4dc 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -104,14 +104,14 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
CurveModifierData *cmd = (CurveModifierData *)md;
Mesh *mesh_src = NULL;
if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
struct MDeformVert *dvert = NULL;
@@ -124,7 +124,7 @@ static void deformVerts(ModifierData *md,
BKE_curve_deform_coords(cmd->object,
ctx->object,
vertexCos,
- numVerts,
+ verts_num,
dvert,
defgrp_index,
cmd->flag,
@@ -140,10 +140,10 @@ static void deformVertsEM(ModifierData *md,
BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
if (mesh != NULL) {
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}
@@ -162,7 +162,7 @@ static void deformVertsEM(ModifierData *md,
BKE_curve_deform_coords_with_editmesh(cmd->object,
ctx->object,
vertexCos,
- numVerts,
+ verts_num,
defgrp_index,
cmd->flag,
cmd->defaxis - 1,
@@ -172,7 +172,7 @@ static void deformVertsEM(ModifierData *md,
BKE_curve_deform_coords(cmd->object,
ctx->object,
vertexCos,
- numVerts,
+ verts_num,
NULL,
defgrp_index,
cmd->flag,
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 2f35ffb3e18..ca48d4fedd8 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -269,7 +269,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- const int numVerts)
+ const int verts_num)
{
Object *ob = ctx->object;
MVert *mvert;
@@ -299,7 +299,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
Tex *tex_target = dmd->texture;
if (tex_target != NULL) {
- tex_co = MEM_calloc_arrayN((size_t)numVerts, sizeof(*tex_co), "displaceModifier_do tex_co");
+ tex_co = MEM_calloc_arrayN((size_t)verts_num, sizeof(*tex_co), "displaceModifier_do tex_co");
MOD_get_texture_coords((MappingInfoModifierData *)dmd, ctx, ob, mesh, vertexCos, tex_co);
MOD_init_texture((MappingInfoModifierData *)dmd, ctx);
@@ -319,9 +319,9 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
}
clnors = CustomData_get_layer(ldata, CD_NORMAL);
- vert_clnors = MEM_malloc_arrayN(numVerts, sizeof(*vert_clnors), __func__);
+ vert_clnors = MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__);
BKE_mesh_normals_loop_to_vertex(
- numVerts, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors);
+ verts_num, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors);
}
else {
direction = MOD_DISP_DIR_NOR;
@@ -355,8 +355,8 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
}
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numVerts > 512);
- BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, &settings);
+ settings.use_threading = (verts_num > 512);
+ BLI_task_parallel_range(0, verts_num, &data, displaceModifier_do_task, &settings);
if (data.pool != NULL) {
BKE_image_pool_free(data.pool);
@@ -375,11 +375,12 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
- displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
+ displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -391,17 +392,17 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, NULL, numVerts, false, false);
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(Campbell): use edit-mode data only (remove this line). */
if (mesh_src != NULL) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, numVerts);
+ displaceModifier_do((DisplaceModifierData *)md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index 33b090b9577..b3bcd181de9 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -279,12 +279,12 @@ static void remap_faces_3_6_9_12(Mesh *mesh,
}
static void remap_uvs_3_6_9_12(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
{
MTFace *mf, *df1, *df2, *df3;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -339,12 +339,12 @@ static void remap_faces_5_10(Mesh *mesh,
}
static void remap_uvs_5_10(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
{
MTFace *mf, *df1, *df2;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -411,12 +411,12 @@ static void remap_faces_15(Mesh *mesh,
}
static void remap_uvs_15(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
{
MTFace *mf, *df1, *df2, *df3, *df4;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -487,12 +487,12 @@ static void remap_faces_7_11_13_14(Mesh *mesh,
}
static void remap_uvs_7_11_13_14(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2, int c3)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2, int c3)
{
MTFace *mf, *df1, *df2, *df3;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -547,12 +547,12 @@ static void remap_faces_19_21_22(Mesh *mesh,
}
static void remap_uvs_19_21_22(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
{
MTFace *mf, *df1, *df2;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -609,12 +609,12 @@ static void remap_faces_23(Mesh *mesh,
}
static void remap_uvs_23(
- Mesh *mesh, Mesh *split, int numlayer, int i, int cur, int c0, int c1, int c2)
+ Mesh *mesh, Mesh *split, int layers_num, int i, int cur, int c0, int c1, int c2)
{
MTFace *mf, *df1, *df2;
int l;
- for (l = 0; l < numlayer; l++) {
+ for (l = 0; l < layers_num; l++) {
mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l);
df1 = mf + cur;
df2 = df1 + 1;
@@ -653,7 +653,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
int *fs, totesplit = 0, totfsplit = 0, curdupface = 0;
int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */
uv[4] = {0, 0, 0, 0}; /* To quite gcc barking... */
- int numlayer;
+ int layers_num;
uint ed_v1, ed_v2;
edgehash = BLI_edgehash_new(__func__);
@@ -728,7 +728,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
split_m = BKE_mesh_new_nomain_from_template(mesh, totesplit, 0, totface + totfsplit, 0, 0);
- numlayer = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE);
+ layers_num = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE);
/* copy new faces & verts (is it really this painful with custom data??) */
for (i = 0; i < totvert; i++) {
@@ -814,23 +814,23 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
case 12:
remap_faces_3_6_9_12(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_3_6_9_12(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ if (layers_num) {
+ remap_uvs_3_6_9_12(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
}
break;
case 5:
case 10:
remap_faces_5_10(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_5_10(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ if (layers_num) {
+ remap_uvs_5_10(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
}
break;
case 15:
remap_faces_15(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_15(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ if (layers_num) {
+ remap_uvs_15(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
}
break;
case 7:
@@ -839,8 +839,9 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
case 14:
remap_faces_7_11_13_14(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2], v[3]);
- if (numlayer) {
- remap_uvs_7_11_13_14(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
+ if (layers_num) {
+ remap_uvs_7_11_13_14(
+ mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2], uv[3]);
}
break;
case 19:
@@ -848,15 +849,15 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh)
case 22:
remap_faces_19_21_22(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
- if (numlayer) {
- remap_uvs_19_21_22(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
+ if (layers_num) {
+ remap_uvs_19_21_22(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]);
}
break;
case 23:
remap_faces_23(
mesh, split_m, mf, facepa, vertpa, i, edgehash, curdupface, v[0], v[1], v[2]);
- if (numlayer) {
- remap_uvs_23(mesh, split_m, numlayer, i, curdupface, uv[0], uv[1], uv[2]);
+ if (layers_num) {
+ remap_uvs_23(mesh, split_m, layers_num, i, curdupface, uv[0], uv[1], uv[2]);
}
break;
case 0:
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 513000e3ad6..1000bbf45d6 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -152,14 +152,14 @@ struct HookData_cb {
bool invert_vgroup;
};
-static BLI_bitmap *hook_index_array_to_bitmap(HookModifierData *hmd, const int numVerts)
+static BLI_bitmap *hook_index_array_to_bitmap(HookModifierData *hmd, const int verts_num)
{
- BLI_bitmap *indexar_used = BLI_BITMAP_NEW(numVerts, __func__);
+ BLI_bitmap *indexar_used = BLI_BITMAP_NEW(verts_num, __func__);
int i;
int *index_pt;
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ for (i = 0, index_pt = hmd->indexar; i < hmd->indexar_num; i++, index_pt++) {
const int j = *index_pt;
- if (j < numVerts) {
+ if (j < verts_num) {
BLI_BITMAP_ENABLE(indexar_used, i);
}
}
@@ -275,7 +275,7 @@ static void deformVerts_do(HookModifierData *hmd,
Mesh *mesh,
BMEditMesh *em,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Object *ob_target = hmd->object;
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget);
@@ -365,15 +365,15 @@ static void deformVerts_do(HookModifierData *hmd,
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))) {
- int numVerts_orig = numVerts;
+ int verts_orig_num = verts_num;
if (ob->type == OB_MESH) {
const Mesh *me_orig = ob->data;
- numVerts_orig = me_orig->totvert;
+ verts_orig_num = me_orig->totvert;
}
- BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts_orig);
- for (i = 0; i < numVerts; i++) {
+ BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, verts_orig_num);
+ for (i = 0; i < verts_num; i++) {
int i_orig = origindex_ar[i];
- BLI_assert(i_orig < numVerts_orig);
+ BLI_assert(i_orig < verts_orig_num);
if (BLI_BITMAP_TEST(indexar_used, i_orig)) {
hook_co_apply(&hd, i, dvert ? &dvert[i] : NULL);
}
@@ -382,8 +382,8 @@ static void deformVerts_do(HookModifierData *hmd,
}
else { /* missing mesh or ORIGINDEX */
if ((em != NULL) && (hd.defgrp_index != -1)) {
- BLI_assert(em->bm->totvert == numVerts);
- BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, numVerts);
+ BLI_assert(em->bm->totvert == verts_num);
+ BLI_bitmap *indexar_used = hook_index_array_to_bitmap(hmd, verts_num);
BMIter iter;
BMVert *v;
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
@@ -395,9 +395,9 @@ static void deformVerts_do(HookModifierData *hmd,
MEM_freeN(indexar_used);
}
else {
- for (i = 0, index_pt = hmd->indexar; i < hmd->totindex; i++, index_pt++) {
+ for (i = 0, index_pt = hmd->indexar; i < hmd->indexar_num; i++, index_pt++) {
const int j = *index_pt;
- if (j < numVerts) {
+ if (j < verts_num) {
hook_co_apply(&hd, j, dvert ? &dvert[j] : NULL);
}
}
@@ -406,7 +406,7 @@ static void deformVerts_do(HookModifierData *hmd,
}
else if (hd.defgrp_index != -1) { /* vertex group hook */
if (em != NULL) {
- BLI_assert(em->bm->totvert == numVerts);
+ BLI_assert(em->bm->totvert == verts_num);
BMIter iter;
BMVert *v;
BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) {
@@ -416,7 +416,7 @@ static void deformVerts_do(HookModifierData *hmd,
}
else {
BLI_assert(dvert != NULL);
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
hook_co_apply(&hd, i, &dvert[i]);
}
}
@@ -427,12 +427,13 @@ static void deformVerts(struct ModifierData *md,
const struct ModifierEvalContext *ctx,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
HookModifierData *hmd = (HookModifierData *)md;
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
- deformVerts_do(hmd, ctx, ctx->object, mesh_src, NULL, vertexCos, numVerts);
+ deformVerts_do(hmd, ctx, ctx->object, mesh_src, NULL, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -444,11 +445,11 @@ static void deformVertsEM(struct ModifierData *md,
struct BMEditMesh *editData,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
HookModifierData *hmd = (HookModifierData *)md;
- deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? NULL : editData, vertexCos, numVerts);
+ deformVerts_do(hmd, ctx, ctx->object, mesh, mesh ? NULL : editData, vertexCos, verts_num);
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@@ -526,7 +527,7 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
BKE_curvemapping_blend_write(writer, hmd->curfalloff);
}
- BLO_write_int32_array(writer, hmd->totindex, hmd->indexar);
+ BLO_write_int32_array(writer, hmd->indexar_num, hmd->indexar);
}
static void blendRead(BlendDataReader *reader, ModifierData *md)
@@ -538,7 +539,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
BKE_curvemapping_blend_read(reader, hmd->curfalloff);
}
- BLO_read_int32_array(reader, hmd->totindex, &hmd->indexar);
+ BLO_read_int32_array(reader, hmd->indexar_num, &hmd->indexar);
}
ModifierTypeInfo modifierType_Hook = {
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index d5f3902379d..239cb7f5a5a 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -58,10 +58,10 @@ enum {
typedef struct LaplacianSystem {
bool is_matrix_computed;
bool has_solution;
- int total_verts;
- int total_edges;
- int total_tris;
- int total_anchors;
+ int verts_num;
+ int edges_num;
+ int tris_num;
+ int anchors_num;
int repeat;
char anchor_grp_name[64]; /* Vertex Group name */
float (*co)[3]; /* Original vertex coordinates */
@@ -84,20 +84,20 @@ static LaplacianSystem *newLaplacianSystem(void)
sys->is_matrix_computed = false;
sys->has_solution = false;
- sys->total_verts = 0;
- sys->total_edges = 0;
- sys->total_anchors = 0;
- sys->total_tris = 0;
+ sys->verts_num = 0;
+ sys->edges_num = 0;
+ sys->anchors_num = 0;
+ sys->tris_num = 0;
sys->repeat = 1;
sys->anchor_grp_name[0] = '\0';
return sys;
}
-static LaplacianSystem *initLaplacianSystem(int totalVerts,
- int totalEdges,
- int totalTris,
- int totalAnchors,
+static LaplacianSystem *initLaplacianSystem(int verts_num,
+ int edges_num,
+ int tris_num,
+ int anchors_num,
const char defgrpName[64],
int iterations)
{
@@ -105,18 +105,18 @@ static LaplacianSystem *initLaplacianSystem(int totalVerts,
sys->is_matrix_computed = false;
sys->has_solution = false;
- sys->total_verts = totalVerts;
- sys->total_edges = totalEdges;
- sys->total_tris = totalTris;
- sys->total_anchors = totalAnchors;
+ sys->verts_num = verts_num;
+ sys->edges_num = edges_num;
+ sys->tris_num = tris_num;
+ sys->anchors_num = anchors_num;
sys->repeat = iterations;
BLI_strncpy(sys->anchor_grp_name, defgrpName, sizeof(sys->anchor_grp_name));
- sys->co = MEM_malloc_arrayN(totalVerts, sizeof(float[3]), "DeformCoordinates");
- sys->no = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformNormals");
- sys->delta = MEM_calloc_arrayN(totalVerts, sizeof(float[3]), "DeformDeltas");
- sys->tris = MEM_malloc_arrayN(totalTris, sizeof(int[3]), "DeformFaces");
- sys->index_anchors = MEM_malloc_arrayN((totalAnchors), sizeof(int), "DeformAnchors");
- sys->unit_verts = MEM_calloc_arrayN(totalVerts, sizeof(int), "DeformUnitVerts");
+ sys->co = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "DeformCoordinates");
+ sys->no = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "DeformNormals");
+ sys->delta = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "DeformDeltas");
+ sys->tris = MEM_malloc_arrayN(tris_num, sizeof(int[3]), "DeformFaces");
+ sys->index_anchors = MEM_malloc_arrayN((anchors_num), sizeof(int), "DeformAnchors");
+ sys->unit_verts = MEM_calloc_arrayN(verts_num, sizeof(int), "DeformUnitVerts");
return sys;
}
@@ -146,7 +146,7 @@ static void createFaceRingMap(const int mvert_tot,
MeshElemMap **r_map,
int **r_indices)
{
- int i, j, totalr = 0;
+ int i, j, indices_num = 0;
int *indices, *index_iter;
MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformRingMap");
const MLoopTri *mlt;
@@ -156,10 +156,10 @@ static void createFaceRingMap(const int mvert_tot,
for (j = 0; j < 3; j++) {
const uint v_index = mloop[mlt->tri[j]].v;
map[v_index].count++;
- totalr++;
+ indices_num++;
}
}
- indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformRingIndex");
+ indices = MEM_calloc_arrayN(indices_num, sizeof(int), "DeformRingIndex");
index_iter = indices;
for (i = 0; i < mvert_tot; i++) {
map[i].indices = index_iter;
@@ -184,7 +184,7 @@ static void createVertRingMap(const int mvert_tot,
int **r_indices)
{
MeshElemMap *map = MEM_calloc_arrayN(mvert_tot, sizeof(MeshElemMap), "DeformNeighborsMap");
- int i, vid[2], totalr = 0;
+ int i, vid[2], indices_num = 0;
int *indices, *index_iter;
const MEdge *me;
@@ -193,9 +193,9 @@ static void createVertRingMap(const int mvert_tot,
vid[1] = me->v2;
map[vid[0]].count++;
map[vid[1]].count++;
- totalr += 2;
+ indices_num += 2;
}
- indices = MEM_calloc_arrayN(totalr, sizeof(int), "DeformNeighborsIndex");
+ indices = MEM_calloc_arrayN(indices_num, sizeof(int), "DeformNeighborsIndex");
index_iter = indices;
for (i = 0; i < mvert_tot; i++) {
map[i].indices = index_iter;
@@ -253,7 +253,7 @@ static void initLaplacianMatrix(LaplacianSystem *sys)
int i = 3, j, ti;
int idv[3];
- for (ti = 0; ti < sys->total_tris; ti++) {
+ for (ti = 0; ti < sys->tris_num; ti++) {
const uint *vidt = sys->tris[ti];
const float *co[3];
@@ -305,7 +305,7 @@ static void computeImplictRotations(LaplacianSystem *sys)
float minj, mjt, qj[3], vj[3];
int i, j, ln;
- for (i = 0; i < sys->total_verts; i++) {
+ for (i = 0; i < sys->verts_num; i++) {
normalize_v3(sys->no[i]);
vidn = sys->ringv_map[i].indices;
ln = sys->ringv_map[i].count;
@@ -329,10 +329,10 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys)
float alpha, beta, gamma;
float pj[3], ni[3], di[3];
float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3];
- int i, j, num_fni, k, fi;
+ int i, j, fidn_num, k, fi;
int *fidn;
- for (i = 0; i < sys->total_verts; i++) {
+ for (i = 0; i < sys->verts_num; i++) {
copy_v3_v3(pi, sys->co[i]);
copy_v3_v3(ni, sys->no[i]);
k = sys->unit_verts[i];
@@ -351,8 +351,8 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys)
pi[1] = EIG_linear_solver_variable_get(sys->context, 1, i);
pi[2] = EIG_linear_solver_variable_get(sys->context, 2, i);
zero_v3(ni);
- num_fni = sys->ringf_map[i].count;
- for (fi = 0; fi < num_fni; fi++) {
+ fidn_num = sys->ringf_map[i].count;
+ for (fi = 0; fi < fidn_num; fi++) {
const uint *vin;
fidn = sys->ringf_map[i].indices;
vin = sys->tris[fidn[fi]];
@@ -395,8 +395,8 @@ static void rotateDifferentialCoordinates(LaplacianSystem *sys)
static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
{
int vid, i, j, n, na;
- n = sys->total_verts;
- na = sys->total_anchors;
+ n = sys->verts_num;
+ na = sys->anchors_num;
if (!sys->is_matrix_computed) {
sys->context = EIG_linear_least_squares_solver_new(n + na, n, 3);
@@ -447,7 +447,7 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
}
}
if (sys->has_solution) {
- for (vid = 0; vid < sys->total_verts; vid++) {
+ for (vid = 0; vid < sys->verts_num; vid++) {
vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
@@ -493,7 +493,7 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3])
}
}
if (sys->has_solution) {
- for (vid = 0; vid < sys->total_verts; vid++) {
+ for (vid = 0; vid < sys->verts_num; vid++) {
vertexCos[vid][0] = EIG_linear_solver_variable_get(sys->context, 0, vid);
vertexCos[vid][1] = EIG_linear_solver_variable_get(sys->context, 1, vid);
vertexCos[vid][2] = EIG_linear_solver_variable_get(sys->context, 2, vid);
@@ -520,11 +520,11 @@ static bool isValidVertexGroup(LaplacianDeformModifierData *lmd, Object *ob, Mes
}
static void initSystem(
- LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
+ LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
{
int i;
int defgrp_index;
- int total_anchors;
+ int anchors_num;
float wpaint;
MDeformVert *dvert = NULL;
MDeformVert *dv = NULL;
@@ -532,18 +532,18 @@ static void initSystem(
const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0;
if (isValidVertexGroup(lmd, ob, mesh)) {
- int *index_anchors = MEM_malloc_arrayN(numVerts, sizeof(int), __func__); /* over-alloc */
+ int *index_anchors = MEM_malloc_arrayN(verts_num, sizeof(int), __func__); /* over-alloc */
const MLoopTri *mlooptri;
const MLoop *mloop;
STACK_DECLARE(index_anchors);
- STACK_INIT(index_anchors, numVerts);
+ STACK_INIT(index_anchors, verts_num);
MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index);
BLI_assert(dvert != NULL);
dv = dvert;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) :
BKE_defvert_find_weight(dv, defgrp_index);
dv++;
@@ -552,20 +552,20 @@ static void initSystem(
}
}
- total_anchors = STACK_SIZE(index_anchors);
- lmd->cache_system = initLaplacianSystem(numVerts,
+ anchors_num = STACK_SIZE(index_anchors);
+ lmd->cache_system = initLaplacianSystem(verts_num,
mesh->totedge,
BKE_mesh_runtime_looptri_len(mesh),
- total_anchors,
+ anchors_num,
lmd->anchor_grp_name,
lmd->repeat);
sys = (LaplacianSystem *)lmd->cache_system;
- memcpy(sys->index_anchors, index_anchors, sizeof(int) * total_anchors);
- memcpy(sys->co, vertexCos, sizeof(float[3]) * numVerts);
+ memcpy(sys->index_anchors, index_anchors, sizeof(int) * anchors_num);
+ memcpy(sys->co, vertexCos, sizeof(float[3]) * verts_num);
MEM_freeN(index_anchors);
- lmd->vertexco = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "ModDeformCoordinates");
- memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * numVerts);
- lmd->total_verts = numVerts;
+ lmd->vertexco = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "ModDeformCoordinates");
+ memcpy(lmd->vertexco, vertexCos, sizeof(float[3]) * verts_num);
+ lmd->verts_num = verts_num;
createFaceRingMap(mesh->totvert,
BKE_mesh_runtime_looptri_ensure(mesh),
@@ -579,7 +579,7 @@ static void initSystem(
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
mloop = mesh->mloop;
- for (i = 0; i < sys->total_tris; i++) {
+ for (i = 0; i < sys->tris_num; i++) {
sys->tris[i][0] = mloop[mlooptri[i].tri[0]].v;
sys->tris[i][1] = mloop[mlooptri[i].tri[1]].v;
sys->tris[i][2] = mloop[mlooptri[i].tri[2]].v;
@@ -590,21 +590,21 @@ static void initSystem(
static int isSystemDifferent(LaplacianDeformModifierData *lmd,
Object *ob,
Mesh *mesh,
- int numVerts)
+ int verts_num)
{
int i;
int defgrp_index;
- int total_anchors = 0;
+ int anchors_num = 0;
float wpaint;
MDeformVert *dvert = NULL;
MDeformVert *dv = NULL;
LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system;
const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0;
- if (sys->total_verts != numVerts) {
+ if (sys->verts_num != verts_num) {
return LAPDEFORM_SYSTEM_CHANGE_VERTEXES;
}
- if (sys->total_edges != mesh->totedge) {
+ if (sys->edges_num != mesh->totedge) {
return LAPDEFORM_SYSTEM_CHANGE_EDGES;
}
if (!STREQ(lmd->anchor_grp_name, sys->anchor_grp_name)) {
@@ -615,15 +615,15 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd,
return LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP;
}
dv = dvert;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) :
BKE_defvert_find_weight(dv, defgrp_index);
dv++;
if (wpaint > 0.0f) {
- total_anchors++;
+ anchors_num++;
}
}
- if (sys->total_anchors != total_anchors) {
+ if (sys->anchors_num != anchors_num) {
return LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS;
}
@@ -631,7 +631,7 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd,
}
static void LaplacianDeformModifier_do(
- LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
+ LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
{
float(*filevertexCos)[3];
int sysdif;
@@ -643,22 +643,22 @@ static void LaplacianDeformModifier_do(
deleteLaplacianSystem(sys);
lmd->cache_system = NULL;
}
- lmd->total_verts = 0;
+ lmd->verts_num = 0;
MEM_SAFE_FREE(lmd->vertexco);
return;
}
if (lmd->cache_system) {
- sysdif = isSystemDifferent(lmd, ob, mesh, numVerts);
+ sysdif = isSystemDifferent(lmd, ob, mesh, verts_num);
sys = lmd->cache_system;
if (sysdif) {
if (ELEM(sysdif, LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS, LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP)) {
- filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates");
- memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
+ filevertexCos = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "TempModDeformCoordinates");
+ memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * verts_num);
MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
+ lmd->verts_num = 0;
deleteLaplacianSystem(sys);
lmd->cache_system = NULL;
- initSystem(lmd, ob, mesh, filevertexCos, numVerts);
+ initSystem(lmd, ob, mesh, filevertexCos, verts_num);
sys = lmd->cache_system; /* may have been reallocated */
MEM_SAFE_FREE(filevertexCos);
if (sys) {
@@ -668,11 +668,11 @@ static void LaplacianDeformModifier_do(
else {
if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) {
BKE_modifier_set_error(
- ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts);
+ ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->verts_num, verts_num);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) {
BKE_modifier_set_error(
- ob, &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge);
+ ob, &lmd->modifier, "Edges changed from %d to %d", sys->edges_num, mesh->totedge);
}
else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) {
BKE_modifier_set_error(ob,
@@ -695,18 +695,18 @@ static void LaplacianDeformModifier_do(
lmd->anchor_grp_name);
lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND;
}
- else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) {
- filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempDeformCoordinates");
- memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts);
+ else if (lmd->verts_num > 0 && lmd->verts_num == verts_num) {
+ filevertexCos = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "TempDeformCoordinates");
+ memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * verts_num);
MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
- initSystem(lmd, ob, mesh, filevertexCos, numVerts);
+ lmd->verts_num = 0;
+ initSystem(lmd, ob, mesh, filevertexCos, verts_num);
sys = lmd->cache_system;
MEM_SAFE_FREE(filevertexCos);
laplacianDeformPreview(sys, vertexCos);
}
else {
- initSystem(lmd, ob, mesh, vertexCos, numVerts);
+ initSystem(lmd, ob, mesh, vertexCos, verts_num);
sys = lmd->cache_system;
laplacianDeformPreview(sys, vertexCos);
}
@@ -762,12 +762,13 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
LaplacianDeformModifier_do(
- (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
+ (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -779,10 +780,10 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, NULL, numVerts, false, false);
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(Campbell): use edit-mode data only (remove this line). */
if (mesh_src != NULL) {
@@ -790,7 +791,7 @@ static void deformVertsEM(ModifierData *md,
}
LaplacianDeformModifier_do(
- (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
+ (LaplacianDeformModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -805,7 +806,7 @@ static void freeData(ModifierData *md)
deleteLaplacianSystem(sys);
}
MEM_SAFE_FREE(lmd->vertexco);
- lmd->total_verts = 0;
+ lmd->verts_num = 0;
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
@@ -846,14 +847,14 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
{
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- BLO_write_float3_array(writer, lmd->total_verts, lmd->vertexco);
+ BLO_write_float3_array(writer, lmd->verts_num, lmd->vertexco);
}
static void blendRead(BlendDataReader *reader, ModifierData *md)
{
LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)md;
- BLO_read_float3_array(reader, lmd->total_verts, &lmd->vertexco);
+ BLO_read_float3_array(reader, lmd->verts_num, &lmd->vertexco);
lmd->cache_system = NULL;
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index effe2a5af90..11abe9a4d0a 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -45,12 +45,12 @@ struct BLaplacianSystem {
float *ring_areas; /* Total area per ring. */
float *vlengths; /* Total sum of lengths(edges) per vertex. */
float *vweights; /* Total sum of weights per vertex. */
- int numEdges; /* Number of edges. */
- int numLoops; /* Number of edges. */
- int numPolys; /* Number of faces. */
- int numVerts; /* Number of verts. */
- short *numNeFa; /* Number of neighbors faces around vertex. */
- short *numNeEd; /* Number of neighbors Edges around vertex. */
+ int edges_num; /* Number of edges. */
+ int loops_num; /* Number of edges. */
+ int polys_num; /* Number of faces. */
+ int verts_num; /* Number of verts. */
+ short *ne_fa_num; /* Number of neighbors faces around vertex. */
+ short *ne_ed_num; /* Number of neighbors Edges around vertex. */
bool *zerola; /* Is zero area or length. */
/* Pointers to data. */
@@ -71,7 +71,7 @@ static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRen
static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
- int numPolys,
+ int polys_num,
const MLoop *mloop);
static LaplacianSystem *init_laplacian_system(int a_numEdges,
int a_numPolys,
@@ -89,8 +89,8 @@ static void delete_laplacian_system(LaplacianSystem *sys)
{
MEM_SAFE_FREE(sys->eweights);
MEM_SAFE_FREE(sys->fweights);
- MEM_SAFE_FREE(sys->numNeEd);
- MEM_SAFE_FREE(sys->numNeFa);
+ MEM_SAFE_FREE(sys->ne_ed_num);
+ MEM_SAFE_FREE(sys->ne_fa_num);
MEM_SAFE_FREE(sys->ring_areas);
MEM_SAFE_FREE(sys->vlengths);
MEM_SAFE_FREE(sys->vweights);
@@ -108,14 +108,14 @@ static void delete_laplacian_system(LaplacianSystem *sys)
static void memset_laplacian_system(LaplacianSystem *sys, int val)
{
- memset(sys->eweights, val, sizeof(float) * sys->numEdges);
- memset(sys->fweights, val, sizeof(float[3]) * sys->numLoops);
- memset(sys->numNeEd, val, sizeof(short) * sys->numVerts);
- memset(sys->numNeFa, val, sizeof(short) * sys->numVerts);
- memset(sys->ring_areas, val, sizeof(float) * sys->numVerts);
- memset(sys->vlengths, val, sizeof(float) * sys->numVerts);
- memset(sys->vweights, val, sizeof(float) * sys->numVerts);
- memset(sys->zerola, val, sizeof(bool) * sys->numVerts);
+ memset(sys->eweights, val, sizeof(float) * sys->edges_num);
+ memset(sys->fweights, val, sizeof(float[3]) * sys->loops_num);
+ memset(sys->ne_ed_num, val, sizeof(short) * sys->verts_num);
+ memset(sys->ne_fa_num, val, sizeof(short) * sys->verts_num);
+ memset(sys->ring_areas, val, sizeof(float) * sys->verts_num);
+ memset(sys->vlengths, val, sizeof(float) * sys->verts_num);
+ memset(sys->vweights, val, sizeof(float) * sys->verts_num);
+ memset(sys->zerola, val, sizeof(bool) * sys->verts_num);
}
static LaplacianSystem *init_laplacian_system(int a_numEdges,
@@ -125,19 +125,19 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges,
{
LaplacianSystem *sys;
sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem");
- sys->numEdges = a_numEdges;
- sys->numPolys = a_numPolys;
- sys->numLoops = a_numLoops;
- sys->numVerts = a_numVerts;
-
- sys->eweights = MEM_calloc_arrayN(sys->numEdges, sizeof(float), __func__);
- sys->fweights = MEM_calloc_arrayN(sys->numLoops, sizeof(float[3]), __func__);
- sys->numNeEd = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
- sys->numNeFa = MEM_calloc_arrayN(sys->numVerts, sizeof(short), __func__);
- sys->ring_areas = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->vlengths = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->vweights = MEM_calloc_arrayN(sys->numVerts, sizeof(float), __func__);
- sys->zerola = MEM_calloc_arrayN(sys->numVerts, sizeof(bool), __func__);
+ sys->edges_num = a_numEdges;
+ sys->polys_num = a_numPolys;
+ sys->loops_num = a_numLoops;
+ sys->verts_num = a_numVerts;
+
+ sys->eweights = MEM_calloc_arrayN(sys->edges_num, sizeof(float), __func__);
+ sys->fweights = MEM_calloc_arrayN(sys->loops_num, sizeof(float[3]), __func__);
+ sys->ne_ed_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__);
+ sys->ne_fa_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__);
+ sys->ring_areas = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
+ sys->vlengths = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
+ sys->vweights = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
+ sys->zerola = MEM_calloc_arrayN(sys->verts_num, sizeof(bool), __func__);
return sys;
}
@@ -145,13 +145,13 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges,
static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
- int numPolys,
+ int polys_num,
const MLoop *mloop)
{
int i;
float vol = 0.0f;
- for (i = 0; i < numPolys; i++) {
+ for (i = 0; i < polys_num; i++) {
const MPoly *mp = &mpoly[i];
const MLoop *l_first = &mloop[mp->loopstart];
const MLoop *l_prev = l_first + 1;
@@ -174,7 +174,7 @@ static void volume_preservation(LaplacianSystem *sys, float vini, float vend, sh
if (vend != 0.0f) {
beta = pow(vini / vend, 1.0f / 3.0f);
- for (i = 0; i < sys->numVerts; i++) {
+ for (i = 0; i < sys->verts_num; i++) {
if (flag & MOD_LAPLACIANSMOOTH_X) {
sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) * beta +
sys->vert_centroid[0];
@@ -199,15 +199,15 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
int i;
uint idv1, idv2;
- for (i = 0; i < sys->numEdges; i++) {
+ for (i = 0; i < sys->edges_num; i++) {
idv1 = sys->medges[i].v1;
idv2 = sys->medges[i].v2;
v1 = sys->vertexCos[idv1];
v2 = sys->vertexCos[idv2];
- sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
- sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
+ sys->ne_ed_num[idv1] = sys->ne_ed_num[idv1] + 1;
+ sys->ne_ed_num[idv2] = sys->ne_ed_num[idv2] + 1;
w1 = len_v3v3(v1, v2);
if (w1 < sys->min_area) {
sys->zerola[idv1] = true;
@@ -220,7 +220,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
sys->eweights[i] = w1;
}
- for (i = 0; i < sys->numPolys; i++) {
+ for (i = 0; i < sys->polys_num; i++) {
const MPoly *mp = &sys->mpoly[i];
const MLoop *l_next = &sys->mloop[mp->loopstart];
const MLoop *l_term = l_next + mp->totloop;
@@ -233,7 +233,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
const float *v_next = sys->vertexCos[l_next->v];
const uint l_curr_index = l_curr - sys->mloop;
- sys->numNeFa[l_curr->v] += 1;
+ sys->ne_fa_num[l_curr->v] += 1;
areaf = area_tri_v3(v_prev, v_curr, v_next);
@@ -258,11 +258,12 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
sys->vweights[l_prev->v] += w1 + w2;
}
}
- for (i = 0; i < sys->numEdges; i++) {
+ for (i = 0; i < sys->edges_num; i++) {
idv1 = sys->medges[i].v1;
idv2 = sys->medges[i].v2;
/* if is boundary, apply scale-dependent umbrella operator only with neighbors in boundary */
- if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) {
+ if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] &&
+ sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2]) {
sys->vlengths[idv1] += sys->eweights[i];
sys->vlengths[idv2] += sys->eweights[i];
}
@@ -274,7 +275,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
int i;
uint idv1, idv2;
- for (i = 0; i < sys->numPolys; i++) {
+ for (i = 0; i < sys->polys_num; i++) {
const MPoly *mp = &sys->mpoly[i];
const MLoop *l_next = &sys->mloop[mp->loopstart];
const MLoop *l_term = l_next + mp->totloop;
@@ -285,7 +286,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
const uint l_curr_index = l_curr - sys->mloop;
/* Is ring if number of faces == number of edges around vertex. */
- if (sys->numNeEd[l_curr->v] == sys->numNeFa[l_curr->v] && sys->zerola[l_curr->v] == false) {
+ if (sys->ne_ed_num[l_curr->v] == sys->ne_fa_num[l_curr->v] &&
+ sys->zerola[l_curr->v] == false) {
EIG_linear_solver_matrix_add(sys->context,
l_curr->v,
l_next->v,
@@ -295,7 +297,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
l_prev->v,
sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]);
}
- if (sys->numNeEd[l_next->v] == sys->numNeFa[l_next->v] && sys->zerola[l_next->v] == false) {
+ if (sys->ne_ed_num[l_next->v] == sys->ne_fa_num[l_next->v] &&
+ sys->zerola[l_next->v] == false) {
EIG_linear_solver_matrix_add(sys->context,
l_next->v,
l_curr->v,
@@ -305,7 +308,8 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
l_prev->v,
sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]);
}
- if (sys->numNeEd[l_prev->v] == sys->numNeFa[l_prev->v] && sys->zerola[l_prev->v] == false) {
+ if (sys->ne_ed_num[l_prev->v] == sys->ne_fa_num[l_prev->v] &&
+ sys->zerola[l_prev->v] == false) {
EIG_linear_solver_matrix_add(sys->context,
l_prev->v,
l_curr->v,
@@ -318,12 +322,13 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
}
}
- for (i = 0; i < sys->numEdges; i++) {
+ for (i = 0; i < sys->edges_num; i++) {
idv1 = sys->medges[i].v1;
idv2 = sys->medges[i].v2;
/* Is boundary */
- if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2] &&
- sys->zerola[idv1] == false && sys->zerola[idv2] == false) {
+ if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] &&
+ sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2] && sys->zerola[idv1] == false &&
+ sys->zerola[idv2] == false) {
EIG_linear_solver_matrix_add(
sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]);
EIG_linear_solver_matrix_add(
@@ -340,12 +345,12 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vini = compute_volume(
- sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
+ sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
}
- for (i = 0; i < sys->numVerts; i++) {
+ for (i = 0; i < sys->verts_num; i++) {
if (sys->zerola[i] == false) {
- lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) :
- (lambda_border >= 0.0f ? 1.0f : -1.0f);
+ lam = sys->ne_ed_num[i] == sys->ne_fa_num[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) :
+ (lambda_border >= 0.0f ? 1.0f : -1.0f);
if (flag & MOD_LAPLACIANSMOOTH_X) {
sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) -
sys->vertexCos[i][0]);
@@ -362,13 +367,13 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
}
if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vend = compute_volume(
- sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
+ sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
volume_preservation(sys, vini, vend, flag);
}
}
static void laplaciansmoothModifier_do(
- LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
+ LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
{
LaplacianSystem *sys;
MDeformVert *dvert = NULL;
@@ -378,7 +383,7 @@ static void laplaciansmoothModifier_do(
int defgrp_index;
const bool invert_vgroup = (smd->flag & MOD_LAPLACIANSMOOTH_INVERT_VGROUP) != 0;
- sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, numVerts);
+ sys = init_laplacian_system(mesh->totedge, mesh->totpoly, mesh->totloop, verts_num);
if (!sys) {
return;
}
@@ -395,12 +400,12 @@ static void laplaciansmoothModifier_do(
sys->vert_centroid[2] = 0.0f;
memset_laplacian_system(sys, 0);
- sys->context = EIG_linear_least_squares_solver_new(numVerts, numVerts, 3);
+ sys->context = EIG_linear_least_squares_solver_new(verts_num, verts_num, 3);
init_laplacian_matrix(sys);
for (iter = 0; iter < smd->repeat; iter++) {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
EIG_linear_solver_variable_set(sys->context, 0, i, vertexCos[i][0]);
EIG_linear_solver_variable_set(sys->context, 1, i, vertexCos[i][1]);
EIG_linear_solver_variable_set(sys->context, 2, i, vertexCos[i][2]);
@@ -408,12 +413,12 @@ static void laplaciansmoothModifier_do(
add_v3_v3(sys->vert_centroid, vertexCos[i]);
}
}
- if (iter == 0 && numVerts > 0) {
- mul_v3_fl(sys->vert_centroid, 1.0f / (float)numVerts);
+ if (iter == 0 && verts_num > 0) {
+ mul_v3_fl(sys->vert_centroid, 1.0f / (float)verts_num);
}
dv = dvert;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
EIG_linear_solver_right_hand_side_add(sys->context, 0, i, vertexCos[i][0]);
EIG_linear_solver_right_hand_side_add(sys->context, 1, i, vertexCos[i][1]);
EIG_linear_solver_right_hand_side_add(sys->context, 2, i, vertexCos[i][2]);
@@ -433,7 +438,7 @@ static void laplaciansmoothModifier_do(
sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w;
w = sys->vlengths[i];
sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
- if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) {
EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint);
}
else {
@@ -447,7 +452,7 @@ static void laplaciansmoothModifier_do(
w = sys->vlengths[i];
sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
- if (sys->numNeEd[i] == sys->numNeFa[i]) {
+ if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) {
EIG_linear_solver_matrix_add(sys->context,
i,
i,
@@ -522,18 +527,18 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src;
- if (numVerts == 0) {
+ if (verts_num == 0) {
return;
}
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
laplaciansmoothModifier_do(
- (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
+ (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -545,15 +550,15 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src;
- if (numVerts == 0) {
+ if (verts_num == 0) {
return;
}
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(Campbell): use edit-mode data only (remove this line). */
if (mesh_src != NULL) {
@@ -561,7 +566,7 @@ static void deformVertsEM(ModifierData *md,
}
laplaciansmoothModifier_do(
- (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, numVerts);
+ (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index 1017f6cca1a..832372304a0 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -94,18 +94,18 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
LatticeModifierData *lmd = (LatticeModifierData *)md;
struct Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
BKE_lattice_deform_coords_with_mesh(lmd->object,
ctx->object,
vertexCos,
- numVerts,
+ verts_num,
lmd->flag,
lmd->name,
lmd->strength,
@@ -121,10 +121,10 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *em,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
if (mesh != NULL) {
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, verts_num);
return;
}
@@ -133,7 +133,7 @@ static void deformVertsEM(ModifierData *md,
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
BKE_lattice_deform_coords_with_editmesh(
- lmd->object, ctx->object, vertexCos, numVerts, lmd->flag, lmd->name, lmd->strength, em);
+ lmd->object, ctx->object, vertexCos, verts_num, lmd->flag, lmd->name, lmd->strength, em);
}
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index 1cb720f4b02..cb26bd1b26b 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -145,58 +145,58 @@ static void invert_boolean_array(MutableSpan<bool> array)
static void compute_masked_vertices(Span<bool> vertex_mask,
MutableSpan<int> r_vertex_map,
- uint *r_num_masked_vertices)
+ uint *r_verts_masked_num)
{
BLI_assert(vertex_mask.size() == r_vertex_map.size());
- uint num_masked_vertices = 0;
+ uint verts_masked_num = 0;
for (uint i_src : r_vertex_map.index_range()) {
if (vertex_mask[i_src]) {
- r_vertex_map[i_src] = num_masked_vertices;
- num_masked_vertices++;
+ r_vertex_map[i_src] = verts_masked_num;
+ verts_masked_num++;
}
else {
r_vertex_map[i_src] = -1;
}
}
- *r_num_masked_vertices = num_masked_vertices;
+ *r_verts_masked_num = verts_masked_num;
}
static void computed_masked_edges(const Mesh *mesh,
Span<bool> vertex_mask,
MutableSpan<int> r_edge_map,
- uint *r_num_masked_edges)
+ uint *r_edges_masked_num)
{
BLI_assert(mesh->totedge == r_edge_map.size());
- uint num_masked_edges = 0;
+ uint edges_masked_num = 0;
for (int i : IndexRange(mesh->totedge)) {
const MEdge &edge = mesh->medge[i];
/* only add if both verts will be in new mesh */
if (vertex_mask[edge.v1] && vertex_mask[edge.v2]) {
- r_edge_map[i] = num_masked_edges;
- num_masked_edges++;
+ r_edge_map[i] = edges_masked_num;
+ edges_masked_num++;
}
else {
r_edge_map[i] = -1;
}
}
- *r_num_masked_edges = num_masked_edges;
+ *r_edges_masked_num = edges_masked_num;
}
static void computed_masked_edges_smooth(const Mesh *mesh,
Span<bool> vertex_mask,
MutableSpan<int> r_edge_map,
- uint *r_num_masked_edges,
- uint *r_num_add_vertices)
+ uint *r_edges_masked_num,
+ uint *r_verts_add_num)
{
BLI_assert(mesh->totedge == r_edge_map.size());
- uint num_masked_edges = 0;
- uint num_add_vertices = 0;
+ uint edges_masked_num = 0;
+ uint verts_add_num = 0;
for (int i : IndexRange(mesh->totedge)) {
const MEdge &edge = mesh->medge[i];
@@ -204,36 +204,36 @@ static void computed_masked_edges_smooth(const Mesh *mesh,
bool v1 = vertex_mask[edge.v1];
bool v2 = vertex_mask[edge.v2];
if (v1 && v2) {
- r_edge_map[i] = num_masked_edges;
- num_masked_edges++;
+ r_edge_map[i] = edges_masked_num;
+ edges_masked_num++;
}
else if (v1 != v2) {
r_edge_map[i] = -2;
- num_add_vertices++;
+ verts_add_num++;
}
else {
r_edge_map[i] = -1;
}
}
- num_masked_edges += num_add_vertices;
- *r_num_masked_edges = num_masked_edges;
- *r_num_add_vertices = num_add_vertices;
+ edges_masked_num += verts_add_num;
+ *r_edges_masked_num = edges_masked_num;
+ *r_verts_add_num = verts_add_num;
}
static void computed_masked_polygons(const Mesh *mesh,
Span<bool> vertex_mask,
Vector<int> &r_masked_poly_indices,
Vector<int> &r_loop_starts,
- uint *r_num_masked_polys,
- uint *r_num_masked_loops)
+ uint *r_polys_masked_num,
+ uint *r_loops_masked_num)
{
BLI_assert(mesh->totvert == vertex_mask.size());
r_masked_poly_indices.reserve(mesh->totpoly);
r_loop_starts.reserve(mesh->totpoly);
- uint num_masked_loops = 0;
+ uint loops_masked_num = 0;
for (int i : IndexRange(mesh->totpoly)) {
const MPoly &poly_src = mesh->mpoly[i];
@@ -248,35 +248,35 @@ static void computed_masked_polygons(const Mesh *mesh,
if (all_verts_in_mask) {
r_masked_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_masked_loops);
- num_masked_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(loops_masked_num);
+ loops_masked_num += poly_src.totloop;
}
}
- *r_num_masked_polys = r_masked_poly_indices.size();
- *r_num_masked_loops = num_masked_loops;
+ *r_polys_masked_num = r_masked_poly_indices.size();
+ *r_loops_masked_num = loops_masked_num;
}
static void compute_interpolated_polygons(const Mesh *mesh,
Span<bool> vertex_mask,
- uint num_add_vertices,
- uint num_masked_loops,
+ uint verts_add_num,
+ uint loops_masked_num,
Vector<int> &r_masked_poly_indices,
Vector<int> &r_loop_starts,
- uint *r_num_add_edges,
- uint *r_num_add_polys,
- uint *r_num_add_loops)
+ uint *r_edges_add_num,
+ uint *r_polys_add_num,
+ uint *r_loops_add_num)
{
BLI_assert(mesh->totvert == vertex_mask.size());
/* Can't really know ahead of time how much space to use exactly. Estimate limit instead. */
/* NOTE: this reserve can only lift the capacity if there are ngons, which get split. */
- r_masked_poly_indices.reserve(r_masked_poly_indices.size() + num_add_vertices);
- r_loop_starts.reserve(r_loop_starts.size() + num_add_vertices);
+ r_masked_poly_indices.reserve(r_masked_poly_indices.size() + verts_add_num);
+ r_loop_starts.reserve(r_loop_starts.size() + verts_add_num);
- uint num_add_edges = 0;
- uint num_add_polys = 0;
- uint num_add_loops = 0;
+ uint edges_add_num = 0;
+ uint polys_add_num = 0;
+ uint loops_add_num = 0;
for (int i : IndexRange(mesh->totpoly)) {
const MPoly &poly_src = mesh->mpoly[i];
@@ -306,10 +306,10 @@ static void compute_interpolated_polygons(const Mesh *mesh,
else if (!v_loop_in_mask && v_loop_in_mask_last) {
BLI_assert(dst_totloop > 2);
r_masked_poly_indices.append(i);
- r_loop_starts.append(num_masked_loops + num_add_loops);
- num_add_loops += dst_totloop;
- num_add_polys++;
- num_add_edges++;
+ r_loop_starts.append(loops_masked_num + loops_add_num);
+ loops_add_num += dst_totloop;
+ polys_add_num++;
+ edges_add_num++;
dst_totloop = -1;
}
else if (v_loop_in_mask && v_loop_in_mask_last) {
@@ -322,9 +322,9 @@ static void compute_interpolated_polygons(const Mesh *mesh,
}
}
- *r_num_add_edges = num_add_edges;
- *r_num_add_polys = num_add_polys;
- *r_num_add_loops = num_add_loops;
+ *r_edges_add_num = edges_add_num;
+ *r_polys_add_num = polys_add_num;
+ *r_loops_add_num = loops_add_num;
}
static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
@@ -363,15 +363,15 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh,
MDeformVert *dvert,
int defgrp_index,
float threshold,
- uint num_masked_edges,
- uint num_add_verts,
+ uint edges_masked_num,
+ uint verts_add_num,
MutableSpan<int> r_edge_map)
{
BLI_assert(src_mesh.totvert == vertex_mask.size());
BLI_assert(src_mesh.totedge == r_edge_map.size());
- uint vert_index = dst_mesh.totvert - num_add_verts;
- uint edge_index = num_masked_edges - num_add_verts;
+ uint vert_index = dst_mesh.totvert - verts_add_num;
+ uint edge_index = edges_masked_num - verts_add_num;
for (int i_src : IndexRange(src_mesh.totedge)) {
if (r_edge_map[i_src] != -1) {
int i_dst = r_edge_map[i_src];
@@ -416,7 +416,7 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh,
}
}
BLI_assert(vert_index == dst_mesh.totvert);
- BLI_assert(edge_index == num_masked_edges);
+ BLI_assert(edge_index == edges_masked_num);
}
static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh,
@@ -448,9 +448,9 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
Span<int> edge_map,
Span<int> masked_poly_indices,
Span<int> new_loop_starts,
- int num_masked_polys)
+ int polys_masked_num)
{
- for (const int i_dst : IndexRange(num_masked_polys)) {
+ for (const int i_dst : IndexRange(polys_masked_num)) {
const int i_src = masked_poly_indices[i_dst];
const MPoly &mp_src = src_mesh.mpoly[i_src];
@@ -483,14 +483,14 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
float threshold,
Span<int> masked_poly_indices,
Span<int> new_loop_starts,
- int num_masked_polys,
- int num_add_edges)
+ int polys_masked_num,
+ int edges_add_num)
{
- int edge_index = dst_mesh.totedge - num_add_edges;
+ int edge_index = dst_mesh.totedge - edges_add_num;
int sub_poly_index = 0;
int last_i_src = -1;
for (const int i_dst :
- IndexRange(num_masked_polys, masked_poly_indices.size() - num_masked_polys)) {
+ IndexRange(polys_masked_num, masked_poly_indices.size() - polys_masked_num)) {
const int i_src = masked_poly_indices[i_dst];
if (i_src == last_i_src) {
sub_poly_index++;
@@ -662,53 +662,52 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
}
Array<int> vertex_map(mesh->totvert);
- uint num_masked_vertices;
- compute_masked_vertices(vertex_mask, vertex_map, &num_masked_vertices);
+ uint verts_masked_num;
+ compute_masked_vertices(vertex_mask, vertex_map, &verts_masked_num);
Array<int> edge_map(mesh->totedge);
- uint num_masked_edges;
- uint num_add_vertices;
+ uint edges_masked_num;
+ uint verts_add_num;
if (use_interpolation) {
- computed_masked_edges_smooth(
- mesh, vertex_mask, edge_map, &num_masked_edges, &num_add_vertices);
+ computed_masked_edges_smooth(mesh, vertex_mask, edge_map, &edges_masked_num, &verts_add_num);
}
else {
- computed_masked_edges(mesh, vertex_mask, edge_map, &num_masked_edges);
- num_add_vertices = 0;
+ computed_masked_edges(mesh, vertex_mask, edge_map, &edges_masked_num);
+ verts_add_num = 0;
}
Vector<int> masked_poly_indices;
Vector<int> new_loop_starts;
- uint num_masked_polys;
- uint num_masked_loops;
+ uint polys_masked_num;
+ uint loops_masked_num;
computed_masked_polygons(mesh,
vertex_mask,
masked_poly_indices,
new_loop_starts,
- &num_masked_polys,
- &num_masked_loops);
+ &polys_masked_num,
+ &loops_masked_num);
- uint num_add_edges = 0;
- uint num_add_polys = 0;
- uint num_add_loops = 0;
+ uint edges_add_num = 0;
+ uint polys_add_num = 0;
+ uint loops_add_num = 0;
if (use_interpolation) {
compute_interpolated_polygons(mesh,
vertex_mask,
- num_add_vertices,
- num_masked_loops,
+ verts_add_num,
+ loops_masked_num,
masked_poly_indices,
new_loop_starts,
- &num_add_edges,
- &num_add_polys,
- &num_add_loops);
+ &edges_add_num,
+ &polys_add_num,
+ &loops_add_num);
}
Mesh *result = BKE_mesh_new_nomain_from_template(mesh,
- num_masked_vertices + num_add_vertices,
- num_masked_edges + num_add_edges,
+ verts_masked_num + verts_add_num,
+ edges_masked_num + edges_add_num,
0,
- num_masked_loops + num_add_loops,
- num_masked_polys + num_add_polys);
+ loops_masked_num + loops_add_num,
+ polys_masked_num + polys_add_num);
copy_masked_vertices_to_new_mesh(*mesh, *result, vertex_map);
if (use_interpolation) {
@@ -719,8 +718,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
dvert,
defgrp_index,
mmd->threshold,
- num_masked_edges,
- num_add_vertices,
+ edges_masked_num,
+ verts_add_num,
edge_map);
}
else {
@@ -732,7 +731,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
edge_map,
masked_poly_indices,
new_loop_starts,
- num_masked_polys);
+ polys_masked_num);
if (use_interpolation) {
add_interpolated_polys_to_new_mesh(*mesh,
*result,
@@ -744,8 +743,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx)
mmd->threshold,
masked_poly_indices,
new_loop_starts,
- num_masked_polys,
- num_add_edges);
+ polys_masked_num,
+ edges_add_num);
}
BKE_mesh_calc_edges_loose(result);
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 3e022a5951d..e5a62ba96b6 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -77,7 +77,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
Object *ob,
Mesh *mesh,
float (*vertexCos_Real)[3],
- int numVerts)
+ int verts_num)
{
const bool use_factor = mcmd->factor < 1.0f;
int influence_group_index;
@@ -87,7 +87,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
float(*vertexCos_Store)[3] = (use_factor || influence_group_index != -1 ||
(mcmd->deform_mode == MOD_MESHCACHE_DEFORM_INTEGRATE)) ?
MEM_malloc_arrayN(
- numVerts, sizeof(*vertexCos_Store), __func__) :
+ verts_num, sizeof(*vertexCos_Store), __func__) :
NULL;
float(*vertexCos)[3] = vertexCos_Store ? vertexCos_Store : vertexCos_Real;
@@ -151,11 +151,11 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
switch (mcmd->type) {
case MOD_MESHCACHE_TYPE_MDD:
ok = MOD_meshcache_read_mdd_times(
- filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ filepath, vertexCos, verts_num, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
break;
case MOD_MESHCACHE_TYPE_PC2:
ok = MOD_meshcache_read_pc2_times(
- filepath, vertexCos, numVerts, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
+ filepath, vertexCos, verts_num, mcmd->interp, time, fps, mcmd->time_mode, &err_str);
break;
default:
ok = false;
@@ -171,7 +171,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
if (UNLIKELY(ob->type != OB_MESH)) {
BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' only valid for Mesh objects");
}
- else if (UNLIKELY(me->totvert != numVerts)) {
+ else if (UNLIKELY(me->totvert != verts_num)) {
BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' original mesh vertex mismatch");
}
else if (UNLIKELY(me->totpoly == 0)) {
@@ -182,11 +182,11 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
int i;
float(*vertexCos_Source)[3] = MEM_malloc_arrayN(
- numVerts, sizeof(*vertexCos_Source), __func__);
- float(*vertexCos_New)[3] = MEM_malloc_arrayN(numVerts, sizeof(*vertexCos_New), __func__);
+ verts_num, sizeof(*vertexCos_Source), __func__);
+ float(*vertexCos_New)[3] = MEM_malloc_arrayN(verts_num, sizeof(*vertexCos_New), __func__);
MVert *mv = me->mvert;
- for (i = 0; i < numVerts; i++, mv++) {
+ for (i = 0; i < verts_num; i++, mv++) {
copy_v3_v3(vertexCos_Source[i], mv->co);
}
@@ -204,7 +204,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
);
/* write the corrected locations back into the result */
- memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * numVerts);
+ memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * verts_num);
MEM_freeN(vertexCos_Source);
MEM_freeN(vertexCos_New);
@@ -244,7 +244,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
if (use_matrix) {
int i;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
mul_m3_v3(mat, vertexCos[i]);
}
}
@@ -260,7 +260,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
mcmd->factor :
0.0f;
if (mesh->dvert != NULL) {
- for (int i = 0; i < numVerts; i++) {
+ for (int i = 0; i < verts_num; i++) {
/* For each vertex, compute its blending factor between the mesh cache (for `fac = 0`)
* and the former position of the vertex (for `fac = 1`). */
const MDeformVert *currentIndexDVert = dvert + i;
@@ -275,10 +275,10 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
}
else if (use_factor) {
/* Influence_group_index is -1. */
- interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, numVerts * 3);
+ interp_vn_vn(*vertexCos_Real, *vertexCos_Store, mcmd->factor, verts_num * 3);
}
else {
- memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * numVerts);
+ memcpy(vertexCos_Real, vertexCos_Store, sizeof(*vertexCos_Store) * verts_num);
}
}
@@ -290,7 +290,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
@@ -299,9 +299,9 @@ static void deformVerts(ModifierData *md,
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
/* `mesh_src` is only needed for vertex groups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
- meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -313,7 +313,7 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
@@ -322,13 +322,14 @@ static void deformVertsEM(ModifierData *md,
if (ctx->object->type == OB_MESH && mcmd->defgrp_name[0] != '\0') {
/* `mesh_src` is only needed for vertex groups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
}
if (mesh_src != NULL) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, numVerts);
+ meshcache_do(mcmd, scene, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
index 66b5f3ff9b2..67a01b1c8d5 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -96,22 +96,22 @@ static bool meshcache_read_mdd_range_from_time(FILE *fp,
return false;
}
- size_t num_frames_read = 0;
- size_t num_frames_expect = mdd_head.frame_tot;
+ size_t frames_num_read = 0;
+ size_t frames_num_expect = mdd_head.frame_tot;
errno = 0;
for (i = 0; i < mdd_head.frame_tot; i++) {
- num_frames_read += fread(&f_time, sizeof(float), 1, fp);
+ frames_num_read += fread(&f_time, sizeof(float), 1, fp);
#ifdef __LITTLE_ENDIAN__
BLI_endian_switch_float(&f_time);
#endif
if (f_time >= time) {
- num_frames_expect = i + 1;
+ frames_num_expect = i + 1;
break;
}
f_time_prev = f_time;
}
- if (num_frames_read != num_frames_expect) {
+ if (frames_num_read != frames_num_expect) {
*err_str = errno ? strerror(errno) : "Timestamp read failed";
return false;
}
@@ -160,14 +160,14 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
return false;
}
- size_t num_verts_read = 0;
+ size_t verts_read_num = 0;
errno = 0;
if (factor >= 1.0f) {
#if 1
float *vco = *vertexCos;
uint i;
for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) {
- num_verts_read += fread(vco, sizeof(float[3]), 1, fp);
+ verts_read_num += fread(vco, sizeof(float[3]), 1, fp);
# ifdef __LITTLE_ENDIAN__
BLI_endian_switch_float(vco + 0);
@@ -192,7 +192,7 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
uint i;
for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) {
float tvec[3];
- num_verts_read += fread(tvec, sizeof(float[3]), 1, fp);
+ verts_read_num += fread(tvec, sizeof(float[3]), 1, fp);
#ifdef __LITTLE_ENDIAN__
BLI_endian_switch_float(tvec + 0);
@@ -206,7 +206,7 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
}
}
- if (num_verts_read != mdd_head.verts_tot) {
+ if (verts_read_num != mdd_head.verts_tot) {
*err_str = errno ? strerror(errno) : "Vertex coordinate read failed";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 54ea27d0085..27fea20bb13 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -137,13 +137,13 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
return false;
}
- size_t num_verts_read = 0;
+ size_t verts_read_num = 0;
errno = 0;
if (factor >= 1.0f) {
float *vco = *vertexCos;
uint i;
for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) {
- num_verts_read += fread(vco, sizeof(float[3]), 1, fp);
+ verts_read_num += fread(vco, sizeof(float[3]), 1, fp);
#ifdef __BIG_ENDIAN__
BLI_endian_switch_float(vco + 0);
@@ -158,7 +158,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
uint i;
for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) {
float tvec[3];
- num_verts_read += fread(tvec, sizeof(float[3]), 1, fp);
+ verts_read_num += fread(tvec, sizeof(float[3]), 1, fp);
#ifdef __BIG_ENDIAN__
BLI_endian_switch_float(tvec + 0);
@@ -172,7 +172,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
}
}
- if (num_verts_read != pc2_head.verts_tot) {
+ if (verts_read_num != pc2_head.verts_tot) {
*err_str = errno ? strerror(errno) : "Vertex coordinate read failed";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index f15cdfe0c4e..09e6819a2ae 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -222,7 +222,7 @@ static float meshdeform_dynamic_bind(MeshDeformModifierData *mmd, float (*dco)[3
cell = &mmd->dyngrid[a];
inf = mmd->dyninfluences + cell->offset;
- for (j = 0; j < cell->totinfluence; j++, inf++) {
+ for (j = 0; j < cell->influences_num; j++, inf++) {
cageco = dco[inf->vertex];
cageweight = weight * inf->weight;
#ifdef BLI_HAVE_SSE2
@@ -324,7 +324,7 @@ static void meshdeformModifier_do(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ const int verts_num)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
Object *ob = ctx->object;
@@ -333,7 +333,7 @@ static void meshdeformModifier_do(ModifierData *md,
MDeformVert *dvert = NULL;
float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4];
float(*dco)[3] = NULL, (*bindcagecos)[3];
- int a, totvert, totcagevert, defgrp_index;
+ int a, cage_verts_num, defgrp_index;
MeshdeformUserdata data;
static int recursive_bind_sentinel = 0;
@@ -375,7 +375,7 @@ static void meshdeformModifier_do(ModifierData *md,
}
if (!recursive_bind_sentinel) {
recursive_bind_sentinel = 1;
- mmd->bindfunc(ob, mmd, cagemesh, (float *)vertexCos, numVerts, cagemat);
+ mmd->bindfunc(ob, mmd, cagemesh, (float *)vertexCos, verts_num, cagemat);
recursive_bind_sentinel = 0;
}
@@ -383,16 +383,15 @@ static void meshdeformModifier_do(ModifierData *md,
}
/* verify we have compatible weights */
- totvert = numVerts;
- totcagevert = BKE_mesh_wrapper_vert_len(cagemesh);
+ cage_verts_num = BKE_mesh_wrapper_vert_len(cagemesh);
- if (mmd->totvert != totvert) {
- BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert);
+ if (mmd->verts_num != verts_num) {
+ BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->verts_num, verts_num);
goto finally;
}
- else if (mmd->totcagevert != totcagevert) {
+ else if (mmd->cage_verts_num != cage_verts_num) {
BKE_modifier_set_error(
- ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert);
+ ob, md, "Cage vertices changed from %d to %d", mmd->cage_verts_num, cage_verts_num);
goto finally;
}
else if (mmd->bindcagecos == NULL) {
@@ -403,14 +402,14 @@ static void meshdeformModifier_do(ModifierData *md,
/* We allocate 1 element extra to make it possible to
* load the values to SSE registers, which are float4.
*/
- dco = MEM_calloc_arrayN((totcagevert + 1), sizeof(*dco), "MDefDco");
- zero_v3(dco[totcagevert]);
+ dco = MEM_calloc_arrayN((cage_verts_num + 1), sizeof(*dco), "MDefDco");
+ zero_v3(dco[cage_verts_num]);
/* setup deformation data */
- BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, totcagevert);
+ BKE_mesh_wrapper_vert_coords_copy(cagemesh, dco, cage_verts_num);
bindcagecos = (float(*)[3])mmd->bindcagecos;
- for (a = 0; a < totcagevert; a++) {
+ for (a = 0; a < cage_verts_num; a++) {
/* Get cage vertex in world-space with binding transform. */
float co[3];
mul_v3_m4v3(co, mmd->bindmat, dco[a]);
@@ -433,7 +432,7 @@ static void meshdeformModifier_do(ModifierData *md,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 16;
- BLI_task_parallel_range(0, totvert, &data, meshdeform_vert_task, &settings);
+ BLI_task_parallel_range(0, verts_num, &data, meshdeform_vert_task, &settings);
finally:
MEM_SAFE_FREE(dco);
@@ -443,13 +442,14 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
- Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ Mesh *mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, NULL, verts_num, false, false);
MOD_previous_vcos_store(md, vertexCos); /* if next modifier needs original vertices */
- meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -461,17 +461,17 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, NULL, numVerts, false, false);
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(Campbell): use edit-mode data only (remove this line). */
if (mesh_src != NULL) {
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- meshdeformModifier_do(md, ctx, mesh_src, vertexCos, numVerts);
+ meshdeformModifier_do(md, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -484,42 +484,42 @@ void BKE_modifier_mdef_compact_influences(ModifierData *md)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
float weight, *weights, totweight;
- int totinfluence, totvert, totcagevert, a, b;
+ int influences_num, verts_num, cage_verts_num, a, b;
weights = mmd->bindweights;
if (!weights) {
return;
}
- totvert = mmd->totvert;
- totcagevert = mmd->totcagevert;
+ verts_num = mmd->verts_num;
+ cage_verts_num = mmd->cage_verts_num;
/* count number of influences above threshold */
- for (b = 0; b < totvert; b++) {
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
+ for (b = 0; b < verts_num; b++) {
+ for (a = 0; a < cage_verts_num; a++) {
+ weight = weights[a + b * cage_verts_num];
if (weight > MESHDEFORM_MIN_INFLUENCE) {
- mmd->totinfluence++;
+ mmd->influences_num++;
}
}
}
/* allocate bind influences */
mmd->bindinfluences = MEM_calloc_arrayN(
- mmd->totinfluence, sizeof(MDefInfluence), "MDefBindInfluence");
- mmd->bindoffsets = MEM_calloc_arrayN((totvert + 1), sizeof(int), "MDefBindOffset");
+ mmd->influences_num, sizeof(MDefInfluence), "MDefBindInfluence");
+ mmd->bindoffsets = MEM_calloc_arrayN((verts_num + 1), sizeof(int), "MDefBindOffset");
/* write influences */
- totinfluence = 0;
+ influences_num = 0;
- for (b = 0; b < totvert; b++) {
- mmd->bindoffsets[b] = totinfluence;
+ for (b = 0; b < verts_num; b++) {
+ mmd->bindoffsets[b] = influences_num;
totweight = 0.0f;
/* sum total weight */
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
+ for (a = 0; a < cage_verts_num; a++) {
+ weight = weights[a + b * cage_verts_num];
if (weight > MESHDEFORM_MIN_INFLUENCE) {
totweight += weight;
@@ -527,18 +527,18 @@ void BKE_modifier_mdef_compact_influences(ModifierData *md)
}
/* assign weights normalized */
- for (a = 0; a < totcagevert; a++) {
- weight = weights[a + b * totcagevert];
+ for (a = 0; a < cage_verts_num; a++) {
+ weight = weights[a + b * cage_verts_num];
if (weight > MESHDEFORM_MIN_INFLUENCE) {
- mmd->bindinfluences[totinfluence].weight = weight / totweight;
- mmd->bindinfluences[totinfluence].vertex = a;
- totinfluence++;
+ mmd->bindinfluences[influences_num].weight = weight / totweight;
+ mmd->bindinfluences[influences_num].vertex = a;
+ influences_num++;
}
}
}
- mmd->bindoffsets[b] = totinfluence;
+ mmd->bindoffsets[b] = influences_num;
/* free */
MEM_freeN(mmd->bindweights);
@@ -586,12 +586,12 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
int size = mmd->dyngridsize;
- BLO_write_struct_array(writer, MDefInfluence, mmd->totinfluence, mmd->bindinfluences);
- BLO_write_int32_array(writer, mmd->totvert + 1, mmd->bindoffsets);
- BLO_write_float3_array(writer, mmd->totcagevert, mmd->bindcagecos);
+ BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->bindinfluences);
+ BLO_write_int32_array(writer, mmd->verts_num + 1, mmd->bindoffsets);
+ BLO_write_float3_array(writer, mmd->cage_verts_num, mmd->bindcagecos);
BLO_write_struct_array(writer, MDefCell, size * size * size, mmd->dyngrid);
- BLO_write_struct_array(writer, MDefInfluence, mmd->totinfluence, mmd->dyninfluences);
- BLO_write_int32_array(writer, mmd->totvert, mmd->dynverts);
+ BLO_write_struct_array(writer, MDefInfluence, mmd->influences_num, mmd->dyninfluences);
+ BLO_write_int32_array(writer, mmd->verts_num, mmd->dynverts);
}
static void blendRead(BlendDataReader *reader, ModifierData *md)
@@ -599,15 +599,15 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
MeshDeformModifierData *mmd = (MeshDeformModifierData *)md;
BLO_read_data_address(reader, &mmd->bindinfluences);
- BLO_read_int32_array(reader, mmd->totvert + 1, &mmd->bindoffsets);
- BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcagecos);
+ BLO_read_int32_array(reader, mmd->verts_num + 1, &mmd->bindoffsets);
+ BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcagecos);
BLO_read_data_address(reader, &mmd->dyngrid);
BLO_read_data_address(reader, &mmd->dyninfluences);
- BLO_read_int32_array(reader, mmd->totvert, &mmd->dynverts);
+ BLO_read_int32_array(reader, mmd->verts_num, &mmd->dynverts);
/* Deprecated storage. */
- BLO_read_float_array(reader, mmd->totvert, &mmd->bindweights);
- BLO_read_float3_array(reader, mmd->totcagevert, &mmd->bindcos);
+ BLO_read_float_array(reader, mmd->verts_num, &mmd->bindweights);
+ BLO_read_float3_array(reader, mmd->cage_verts_num, &mmd->bindcos);
}
ModifierTypeInfo modifierType_MeshDeform = {
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc
index c30ab622842..cfc5b17f37e 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc
@@ -4,7 +4,7 @@
* \ingroup modifiers
*/
-#include <string.h>
+#include <cstring>
#include "BLI_math_vector.h"
#include "BLI_string.h"
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index cc6f23073a3..a4c5ddac5c9 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -281,7 +281,7 @@ static void deformMatrices(ModifierData *md,
Mesh *mesh,
float (*vertex_cos)[3],
float (*deform_matrices)[3][3],
- int num_verts)
+ int verts_num)
{
#if !defined(WITH_OPENSUBDIV)
@@ -313,7 +313,7 @@ static void deformMatrices(ModifierData *md,
return;
}
BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
- BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, num_verts);
+ BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num);
if (subdiv != runtime_data->subdiv) {
BKE_subdiv_free(subdiv);
}
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 94b35c42247..fe05f48a868 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -43,7 +43,7 @@ static void generate_vert_coordinates(Mesh *mesh,
Object *ob,
Object *ob_center,
const float offset[3],
- const int num_verts,
+ const int verts_num,
float (*r_cos)[3],
float r_size[3])
{
@@ -108,7 +108,7 @@ static void generate_vert_coordinates(Mesh *mesh,
/* Else, no need to change coordinates! */
if (do_diff) {
- int i = num_verts;
+ int i = verts_num;
while (i--) {
add_v3_v3(r_cos[i], diff);
}
@@ -122,11 +122,11 @@ static void mix_normals(const float mix_factor,
const bool use_invert_vgroup,
const float mix_limit,
const short mix_mode,
- const int num_verts,
+ const int verts_num,
MLoop *mloop,
float (*nos_old)[3],
float (*nos_new)[3],
- const int num_loops)
+ const int loops_num)
{
/* Mix with org normals... */
float *facs = NULL, *wfac;
@@ -134,12 +134,12 @@ static void mix_normals(const float mix_factor,
int i;
if (dvert) {
- facs = MEM_malloc_arrayN((size_t)num_loops, sizeof(*facs), __func__);
+ facs = MEM_malloc_arrayN((size_t)loops_num, sizeof(*facs), __func__);
BKE_defvert_extract_vgroup_to_loopweights(
- dvert, defgrp_index, num_verts, mloop, num_loops, facs, use_invert_vgroup);
+ dvert, defgrp_index, verts_num, mloop, loops_num, facs, use_invert_vgroup);
}
- for (i = num_loops, no_new = nos_new, no_old = nos_old, wfac = facs; i--;
+ for (i = loops_num, no_new = nos_new, no_old = nos_old, wfac = facs; i--;
no_new++, no_old++, wfac++) {
const float fac = facs ? *wfac * mix_factor : mix_factor;
@@ -177,14 +177,14 @@ static bool polygons_check_flip(MLoop *mloop,
CustomData *ldata,
MPoly *mpoly,
float (*polynors)[3],
- const int num_polys)
+ const int polys_num)
{
MPoly *mp;
MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS);
int i;
bool flipped = false;
- for (i = 0, mp = mpoly; i < num_polys; i++, mp++) {
+ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
float norsum[3] = {0.0f};
float(*no)[3];
int j;
@@ -222,26 +222,26 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
const int defgrp_index,
const bool use_invert_vgroup,
MVert *mvert,
- const int num_verts,
+ const int verts_num,
MEdge *medge,
- const int num_edges,
+ const int edges_num,
MLoop *mloop,
- const int num_loops,
+ const int loops_num,
MPoly *mpoly,
- const int num_polys)
+ const int polys_num)
{
Object *ob_target = enmd->target;
const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
int i;
- float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
- float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
+ float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
+ float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
float size[3];
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
- generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, num_verts, cos, size);
+ generate_vert_coordinates(mesh, ob, ob_target, enmd->offset, verts_num, cos, size);
/**
* size gives us our spheroid coefficients `(A, B, C)`.
@@ -283,7 +283,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
float(*no)[3];
/* We reuse cos to now store the ellipsoid-normal of the verts! */
- for (i = num_loops, ml = mloop, no = nos; i--; ml++, no++) {
+ for (i = loops_num, ml = mloop, no = nos; i--; ml++, no++) {
const int vidx = ml->v;
float *co = cos[vidx];
@@ -313,31 +313,31 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
use_invert_vgroup,
mix_limit,
mix_mode,
- num_verts,
+ verts_num,
mloop,
loopnors,
nos,
- num_loops);
+ loops_num);
}
if (do_polynors_fix &&
polygons_check_flip(
- mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), num_polys)) {
+ mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) {
/* We need to recompute vertex normals! */
BKE_mesh_normals_tag_dirty(mesh);
}
BKE_mesh_normals_loop_custom_set(mvert,
BKE_mesh_vertex_normals_ensure(mesh),
- num_verts,
+ verts_num,
medge,
- num_edges,
+ edges_num,
mloop,
nos,
- num_loops,
+ loops_num,
mpoly,
polynors,
- num_polys,
+ polys_num,
clnors);
MEM_freeN(cos);
@@ -359,20 +359,20 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
const int defgrp_index,
const bool use_invert_vgroup,
MVert *mvert,
- const int num_verts,
+ const int verts_num,
MEdge *medge,
- const int num_edges,
+ const int edges_num,
MLoop *mloop,
- const int num_loops,
+ const int loops_num,
MPoly *mpoly,
- const int num_polys)
+ const int polys_num)
{
Object *ob_target = enmd->target;
const bool do_polynors_fix = (enmd->flag & MOD_NORMALEDIT_NO_POLYNORS_FIX) == 0;
const bool use_parallel_normals = (enmd->flag & MOD_NORMALEDIT_USE_DIRECTION_PARALLEL) != 0;
- float(*nos)[3] = MEM_malloc_arrayN((size_t)num_loops, sizeof(*nos), __func__);
+ float(*nos)[3] = MEM_malloc_arrayN((size_t)loops_num, sizeof(*nos), __func__);
float target_co[3];
int i;
@@ -390,20 +390,20 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
sub_v3_v3v3(no, target_co, enmd->offset);
normalize_v3(no);
- for (i = num_loops; i--;) {
+ for (i = loops_num; i--;) {
copy_v3_v3(nos[i], no);
}
}
else {
- float(*cos)[3] = MEM_malloc_arrayN((size_t)num_verts, sizeof(*cos), __func__);
- generate_vert_coordinates(mesh, ob, ob_target, NULL, num_verts, cos, NULL);
+ float(*cos)[3] = MEM_malloc_arrayN((size_t)verts_num, sizeof(*cos), __func__);
+ generate_vert_coordinates(mesh, ob, ob_target, NULL, verts_num, cos, NULL);
- BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)num_verts, __func__);
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__);
MLoop *ml;
float(*no)[3];
/* We reuse cos to now store the 'to target' normal of the verts! */
- for (i = num_loops, no = nos, ml = mloop; i--; no++, ml++) {
+ for (i = loops_num, no = nos, ml = mloop; i--; no++, ml++) {
const int vidx = ml->v;
float *co = cos[vidx];
@@ -428,30 +428,30 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
use_invert_vgroup,
mix_limit,
mix_mode,
- num_verts,
+ verts_num,
mloop,
loopnors,
nos,
- num_loops);
+ loops_num);
}
if (do_polynors_fix &&
polygons_check_flip(
- mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), num_polys)) {
+ mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) {
BKE_mesh_normals_tag_dirty(mesh);
}
BKE_mesh_normals_loop_custom_set(mvert,
BKE_mesh_vertex_normals_ensure(mesh),
- num_verts,
+ verts_num,
medge,
- num_edges,
+ edges_num,
mloop,
nos,
- num_loops,
+ loops_num,
mpoly,
polynors,
- num_polys,
+ polys_num,
clnors);
MEM_freeN(nos);
@@ -519,10 +519,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
result = mesh;
}
- const int num_verts = result->totvert;
- const int num_edges = result->totedge;
- const int num_loops = result->totloop;
- const int num_polys = result->totpoly;
+ const int verts_num = result->totvert;
+ const int edges_num = result->totedge;
+ const int loops_num = result->totloop;
+ const int polys_num = result->totpoly;
MVert *mvert = result->mvert;
MEdge *medge = result->medge;
MLoop *mloop = result->mloop;
@@ -541,20 +541,20 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
clnors = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
if (use_current_clnors) {
- clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, num_loops);
- loopnors = MEM_malloc_arrayN((size_t)num_loops, sizeof(*loopnors), __func__);
+ clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num);
+ loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__);
BKE_mesh_normals_loop_split(mvert,
vert_normals,
- num_verts,
+ verts_num,
medge,
- num_edges,
+ edges_num,
mloop,
loopnors,
- num_loops,
+ loops_num,
mpoly,
poly_normals,
- num_polys,
+ polys_num,
true,
result->smoothresh,
NULL,
@@ -563,7 +563,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
}
if (clnors == NULL) {
- clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops);
+ clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num);
}
MOD_get_vgroup(ob, result, enmd->defgrp_name, &dvert, &defgrp_index);
@@ -583,13 +583,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
defgrp_index,
use_invert_vgroup,
mvert,
- num_verts,
+ verts_num,
medge,
- num_edges,
+ edges_num,
mloop,
- num_loops,
+ loops_num,
mpoly,
- num_polys);
+ polys_num);
}
else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) {
normalEditModifier_do_directional(enmd,
@@ -606,13 +606,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
defgrp_index,
use_invert_vgroup,
mvert,
- num_verts,
+ verts_num,
medge,
- num_edges,
+ edges_num,
mloop,
- num_loops,
+ loops_num,
mpoly,
- num_polys);
+ polys_num);
}
MEM_SAFE_FREE(loopnors);
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index c1423347413..6ded702ceda 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -249,8 +249,8 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
GenerateOceanGeometryData gogd;
- int num_verts;
- int num_polys;
+ int verts_num;
+ int polys_num;
const bool use_threading = resolution > 4;
@@ -259,8 +259,8 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
gogd.res_x = gogd.rx * omd->repeat_x;
gogd.res_y = gogd.ry * omd->repeat_y;
- num_verts = (gogd.res_x + 1) * (gogd.res_y + 1);
- num_polys = gogd.res_x * gogd.res_y;
+ verts_num = (gogd.res_x + 1) * (gogd.res_y + 1);
+ polys_num = gogd.res_x * gogd.res_y;
gogd.sx = omd->size * omd->spatial_size;
gogd.sy = omd->size * omd->spatial_size;
@@ -270,7 +270,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
gogd.sx /= gogd.rx;
gogd.sy /= gogd.ry;
- result = BKE_mesh_new_nomain(num_verts, 0, 0, num_polys * 4, num_polys);
+ result = BKE_mesh_new_nomain(verts_num, 0, 0, polys_num * 4, polys_num);
BKE_mesh_copy_parameters_for_eval(result, mesh_orig);
gogd.mverts = result->mvert;
@@ -292,7 +292,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
/* add uvs */
if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) {
gogd.mloopuvs = CustomData_add_layer(
- &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, num_polys * 4);
+ &result->ldata, CD_MLOOPUV, CD_CALLOC, NULL, polys_num * 4);
if (gogd.mloopuvs) { /* unlikely to fail */
gogd.ix = 1.0 / gogd.rx;
@@ -377,23 +377,23 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) {
- const int num_polys = result->totpoly;
- const int num_loops = result->totloop;
+ const int polys_num = result->totpoly;
+ const int loops_num = result->totloop;
MLoop *mloops = result->mloop;
MLoopCol *mloopcols = CustomData_add_layer_named(
- &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->foamlayername);
+ &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->foamlayername);
MLoopCol *mloopcols_spray = NULL;
if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) {
mloopcols_spray = CustomData_add_layer_named(
- &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, num_loops, omd->spraylayername);
+ &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->spraylayername);
}
if (mloopcols) { /* unlikely to fail */
MPoly *mpolys = result->mpoly;
MPoly *mp;
- for (i = 0, mp = mpolys; i < num_polys; i++, mp++) {
+ for (i = 0, mp = mpolys; i < polys_num; i++, mp++) {
MLoop *ml = &mloops[mp->loopstart];
MLoopCol *mlcol = &mloopcols[mp->loopstart];
@@ -449,9 +449,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
/* NOTE: tried to parallelized that one and previous foam loop,
* but gives 20% slower results... odd. */
{
- const int num_verts = result->totvert;
+ const int verts_num = result->totvert;
- for (i = 0; i < num_verts; i++) {
+ for (i = 0; i < verts_num; i++) {
float *vco = mverts[i].co;
const float u = OCEAN_CO(size_co_inv, vco[0]);
const float v = OCEAN_CO(size_co_inv, vco[1]);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 6c2651bae1f..7df7ba7c1db 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -100,7 +100,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Mesh *mesh_src = mesh;
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
@@ -118,7 +118,8 @@ static void deformVerts(ModifierData *md,
}
if (mesh_src == NULL) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, vertexCos, numVerts, false, true);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, NULL, vertexCos, verts_num, false, true);
if (mesh_src == NULL) {
return;
}
@@ -235,7 +236,7 @@ static void deformVertsEM(ModifierData *md,
BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
const bool do_temp_mesh = (mesh == NULL);
if (do_temp_mesh) {
@@ -243,7 +244,7 @@ static void deformVertsEM(ModifierData *md,
BM_mesh_bm_to_me(NULL, editData->bm, mesh, &((BMeshToMeshParams){0}));
}
- deformVerts(md, ob, mesh, vertexCos, numVerts);
+ deformVerts(md, ob, mesh, vertexCos, verts_num);
if (derivedData) {
BKE_id_free(NULL, mesh);
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index 5d6be527b2d..6953e89dfc2 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -27,14 +27,14 @@ static void deformVerts(ModifierData *UNUSED(md),
const ModifierEvalContext *ctx,
Mesh *UNUSED(mesh),
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Key *key = BKE_key_from_object(ctx->object);
if (key && key->block.first) {
int deformedVerts_tot;
BKE_key_evaluate_object_ex(
- ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * numVerts);
+ ctx->object, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * verts_num);
}
}
@@ -43,7 +43,7 @@ static void deformMatrices(ModifierData *md,
Mesh *mesh,
float (*vertexCos)[3],
float (*defMats)[3][3],
- int numVerts)
+ int verts_num)
{
Key *key = BKE_key_from_object(ctx->object);
KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
@@ -51,7 +51,7 @@ static void deformMatrices(ModifierData *md,
(void)vertexCos; /* unused */
- if (kb && kb->totelem == numVerts && kb != key->refkey) {
+ if (kb && kb->totelem == verts_num && kb != key->refkey) {
int a;
if (ctx->object->shapeflag & OB_SHAPE_LOCK) {
@@ -61,12 +61,12 @@ static void deformMatrices(ModifierData *md,
scale_m3_fl(scale, kb->curval);
}
- for (a = 0; a < numVerts; a++) {
+ for (a = 0; a < verts_num; a++) {
copy_m3_m3(defMats[a], scale);
}
}
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, verts_num);
}
static void deformVertsEM(ModifierData *md,
@@ -74,12 +74,12 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *UNUSED(editData),
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Key *key = BKE_key_from_object(ctx->object);
if (key && key->type == KEY_RELATIVE) {
- deformVerts(md, ctx, mesh, vertexCos, numVerts);
+ deformVerts(md, ctx, mesh, vertexCos, verts_num);
}
}
@@ -89,7 +89,7 @@ static void deformMatricesEM(ModifierData *UNUSED(md),
Mesh *UNUSED(mesh),
float (*vertexCos)[3],
float (*defMats)[3][3],
- int numVerts)
+ int verts_num)
{
Key *key = BKE_key_from_object(ctx->object);
KeyBlock *kb = BKE_keyblock_from_object(ctx->object);
@@ -97,11 +97,11 @@ static void deformMatricesEM(ModifierData *UNUSED(md),
(void)vertexCos; /* unused */
- if (kb && kb->totelem == numVerts && kb != key->refkey) {
+ if (kb && kb->totelem == verts_num && kb != key->refkey) {
int a;
scale_m3_fl(scale, kb->curval);
- for (a = 0; a < numVerts; a++) {
+ for (a = 0; a < verts_num; a++) {
copy_m3_m3(defMats[a], scale);
}
}
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index 21f8f90585d..488df3d6f4c 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -98,7 +98,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
@@ -108,7 +108,7 @@ static void deformVerts(ModifierData *md,
(swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
/* mesh_src is needed for vgroups, but also used as ShrinkwrapCalcData.vert when projecting.
* Avoid time-consuming mesh conversion for curves when not projecting. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
struct MDeformVert *dvert = NULL;
@@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md,
MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index);
shrinkwrapModifier_deform(
- swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
+ swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -128,14 +128,15 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
ShrinkwrapModifierData *swmd = (ShrinkwrapModifierData *)md;
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
Mesh *mesh_src = NULL;
if ((swmd->vgroup_name[0] != '\0') || (swmd->shrinkType == MOD_SHRINKWRAP_PROJECT)) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -150,7 +151,7 @@ static void deformVertsEM(ModifierData *md,
}
shrinkwrapModifier_deform(
- swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, numVerts);
+ swmd, ctx, scene, ctx->object, mesh_src, dvert, defgrp_index, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 4fbef6f54ae..e3c7f1c423b 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -288,7 +288,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
struct Object *ob,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
int i;
float smd_limit[2], smd_factor;
@@ -355,7 +355,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
float lower = FLT_MAX;
float upper = -FLT_MAX;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float tmp[3];
copy_v3_v3(tmp, vertexCos[i]);
@@ -401,7 +401,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd,
/* Do deformation. */
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- BLI_task_parallel_range(0, numVerts, (void *)&deform_pool_data, simple_helper, &settings);
+ BLI_task_parallel_range(0, verts_num, (void *)&deform_pool_data, simple_helper, &settings);
}
/* SimpleDeform */
@@ -446,17 +446,17 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
Mesh *mesh_src = NULL;
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
- SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -468,14 +468,15 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
struct Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SimpleDeformModifierData *sdmd = (SimpleDeformModifierData *)md;
Mesh *mesh_src = NULL;
if (ctx->object->type == OB_MESH && sdmd->vgroup_name[0] != '\0') {
/* mesh_src is only needed for vgroups. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -483,7 +484,7 @@ static void deformVertsEM(ModifierData *md,
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ SimpleDeformModifier_do(sdmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index e42223e2ad5..b950578ff1b 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -450,18 +450,18 @@ static Frame **collect_hull_frames(
{
SkinNode *f;
Frame **hull_frames;
- int nbr, i;
+ int hull_frames_num, i;
(*tothullframe) = emap[v].count;
hull_frames = MEM_calloc_arrayN(
(*tothullframe), sizeof(Frame *), "hull_from_frames.hull_frames");
- i = 0;
- for (nbr = 0; nbr < emap[v].count; nbr++) {
- const MEdge *e = &medge[emap[v].indices[nbr]];
+ hull_frames_num = 0;
+ for (i = 0; i < emap[v].count; i++) {
+ const MEdge *e = &medge[emap[v].indices[i]];
f = &frames[BKE_mesh_edge_other_vert(e, v)];
/* Can't have adjacent branch nodes yet */
if (f->totframe) {
- hull_frames[i++] = &f->frames[0];
+ hull_frames[hull_frames_num++] = &f->frames[0];
}
else {
(*tothullframe)--;
@@ -649,14 +649,14 @@ static void connection_node_frames(int v,
}
static SkinNode *build_frames(
- const MVert *mvert, int totvert, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat)
+ const MVert *mvert, int verts_num, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat)
{
SkinNode *skin_nodes;
int v;
- skin_nodes = MEM_calloc_arrayN(totvert, sizeof(SkinNode), "build_frames.skin_nodes");
+ skin_nodes = MEM_calloc_arrayN(verts_num, sizeof(SkinNode), "build_frames.skin_nodes");
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
if (emap[v].count <= 1) {
end_node_frames(v, skin_nodes, mvert, nodes, emap, emat);
}
@@ -766,10 +766,10 @@ static void build_emats_stack(BLI_Stack *stack,
static EMat *build_edge_mats(const MVertSkin *vs,
const MVert *mvert,
- int totvert,
+ const int verts_num,
const MEdge *medge,
const MeshElemMap *emap,
- int totedge,
+ const int edges_num,
bool *has_valid_root)
{
BLI_Stack *stack;
@@ -780,12 +780,12 @@ static EMat *build_edge_mats(const MVertSkin *vs,
stack = BLI_stack_new(sizeof(stack_elem), "build_edge_mats.stack");
- visited_e = BLI_BITMAP_NEW(totedge, "build_edge_mats.visited_e");
- emat = MEM_calloc_arrayN(totedge, sizeof(EMat), "build_edge_mats.emat");
+ visited_e = BLI_BITMAP_NEW(edges_num, "build_edge_mats.visited_e");
+ emat = MEM_calloc_arrayN(edges_num, sizeof(EMat), "build_edge_mats.emat");
/* Edge matrices are built from the root nodes, add all roots with
* children to the stack */
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
if (vs[v].flag & MVERT_SKIN_ROOT) {
if (emap[v].count >= 1) {
const MEdge *e = &medge[emap[v].indices[0]];
@@ -800,7 +800,7 @@ static EMat *build_edge_mats(const MVertSkin *vs,
*has_valid_root = true;
}
- else if (totedge == 0) {
+ else if (edges_num == 0) {
/* Vertex-only mesh is valid, mark valid root as well (will display error otherwise). */
*has_valid_root = true;
break;
@@ -837,7 +837,7 @@ static int calc_edge_subdivisions(const MVert *mvert,
float avg_radius;
const bool v1_branch = degree[e->v1] > 2;
const bool v2_branch = degree[e->v2] > 2;
- int num_subdivisions;
+ int subdivisions_num;
/* If either end is a branch node marked 'loose', don't subdivide
* the edge (or subdivide just twice if both are branches) */
@@ -854,27 +854,27 @@ static int calc_edge_subdivisions(const MVert *mvert,
if (avg_radius != 0.0f) {
/* possible (but unlikely) that we overflow INT_MAX */
- float num_subdivisions_fl;
+ float subdivisions_num_fl;
const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co);
- num_subdivisions_fl = (edge_len / avg_radius);
- if (num_subdivisions_fl < NUM_SUBDIVISIONS_MAX) {
- num_subdivisions = (int)num_subdivisions_fl;
+ subdivisions_num_fl = (edge_len / avg_radius);
+ if (subdivisions_num_fl < NUM_SUBDIVISIONS_MAX) {
+ subdivisions_num = (int)subdivisions_num_fl;
}
else {
- num_subdivisions = NUM_SUBDIVISIONS_MAX;
+ subdivisions_num = NUM_SUBDIVISIONS_MAX;
}
}
else {
- num_subdivisions = 0;
+ subdivisions_num = 0;
}
/* If both ends are branch nodes, two intermediate nodes are
* required */
- if (num_subdivisions < 2 && v1_branch && v2_branch) {
- num_subdivisions = 2;
+ if (subdivisions_num < 2 && v1_branch && v2_branch) {
+ subdivisions_num = 2;
}
- return num_subdivisions;
+ return subdivisions_num;
#undef NUM_SUBDIVISIONS_MAX
}
@@ -888,8 +888,8 @@ static Mesh *subdivide_base(Mesh *orig)
MVert *origvert, *outvert;
MEdge *origedge, *outedge, *e;
MDeformVert *origdvert, *outdvert;
- int totorigvert, totorigedge;
- int totsubd, *degree, *edge_subd;
+ int orig_vert_num, orig_edge_num;
+ int subd_num, *degree, *edge_subd;
int i, j, k, u, v;
float radrat;
@@ -897,29 +897,29 @@ static Mesh *subdivide_base(Mesh *orig)
origvert = orig->mvert;
origedge = orig->medge;
origdvert = orig->dvert;
- totorigvert = orig->totvert;
- totorigedge = orig->totedge;
+ orig_vert_num = orig->totvert;
+ orig_edge_num = orig->totedge;
/* Get degree of all vertices */
- degree = MEM_calloc_arrayN(totorigvert, sizeof(int), "degree");
- for (i = 0; i < totorigedge; i++) {
+ degree = MEM_calloc_arrayN(orig_vert_num, sizeof(int), "degree");
+ for (i = 0; i < orig_edge_num; i++) {
degree[origedge[i].v1]++;
degree[origedge[i].v2]++;
}
/* Per edge, store how many subdivisions are needed */
- edge_subd = MEM_calloc_arrayN((uint)totorigedge, sizeof(int), "edge_subd");
- for (i = 0, totsubd = 0; i < totorigedge; i++) {
+ edge_subd = MEM_calloc_arrayN((uint)orig_edge_num, sizeof(int), "edge_subd");
+ for (i = 0, subd_num = 0; i < orig_edge_num; i++) {
edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree);
BLI_assert(edge_subd[i] >= 0);
- totsubd += edge_subd[i];
+ subd_num += edge_subd[i];
}
MEM_freeN(degree);
/* Allocate output mesh */
result = BKE_mesh_new_nomain_from_template(
- orig, totorigvert + totsubd, totorigedge + totsubd, 0, 0, 0);
+ orig, orig_vert_num + subd_num, orig_edge_num + subd_num, 0, 0, 0);
outvert = result->mvert;
outedge = result->medge;
@@ -927,16 +927,16 @@ static Mesh *subdivide_base(Mesh *orig)
outdvert = result->dvert;
/* Copy original vertex data */
- CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, totorigvert);
+ CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, orig_vert_num);
/* Subdivide edges */
- for (i = 0, v = totorigvert; i < totorigedge; i++) {
+ for (i = 0, v = orig_vert_num; i < orig_edge_num; i++) {
struct {
/* Vertex group number */
int def_nr;
float w1, w2;
} *vgroups = NULL, *vg;
- int totvgroup = 0;
+ int vgroups_num = 0;
e = &origedge[i];
@@ -950,8 +950,8 @@ static Mesh *subdivide_base(Mesh *orig)
vg = NULL;
for (k = 0; k < dv2->totweight; k++) {
if (dv1->dw[j].def_nr == dv2->dw[k].def_nr) {
- vg = &vgroups[totvgroup];
- totvgroup++;
+ vg = &vgroups[vgroups_num];
+ vgroups_num++;
break;
}
}
@@ -986,7 +986,7 @@ static Mesh *subdivide_base(Mesh *orig)
interp_v3_v3v3(outnode[v].radius, orignode[e->v1].radius, orignode[e->v2].radius, t);
/* Interpolate vertex group weights */
- for (k = 0; k < totvgroup; k++) {
+ for (k = 0; k < vgroups_num; k++) {
float weight;
vg = &vgroups[k];
@@ -1561,14 +1561,14 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd)
}
static void skin_merge_close_frame_verts(SkinNode *skin_nodes,
- int totvert,
+ int verts_num,
const MeshElemMap *emap,
const MEdge *medge)
{
Frame **hull_frames;
int v, tothullframe;
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
/* Only check branch nodes */
if (!skin_nodes[v].totframe) {
hull_frames = collect_hull_frames(v, skin_nodes, emap, medge, &tothullframe);
@@ -1578,11 +1578,11 @@ static void skin_merge_close_frame_verts(SkinNode *skin_nodes,
}
}
-static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert)
+static void skin_update_merged_vertices(SkinNode *skin_nodes, int verts_num)
{
int v;
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
SkinNode *sn = &skin_nodes[v];
int i, j;
@@ -1601,11 +1601,11 @@ static void skin_update_merged_vertices(SkinNode *skin_nodes, int totvert)
}
}
-static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert)
+static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int verts_num)
{
int v;
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
SkinNode *sn = &skin_nodes[v];
int j;
@@ -1626,11 +1626,11 @@ static void skin_fix_hull_topology(BMesh *bm, SkinNode *skin_nodes, int totvert)
}
}
-static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totvert)
+static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int verts_num)
{
int v;
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
SkinNode *sn = &skin_nodes[v];
/* Assuming here just two frames */
if (sn->flag & SEAM_FRAME) {
@@ -1676,11 +1676,11 @@ static void skin_output_end_nodes(SkinOutput *so, SkinNode *skin_nodes, int totv
static void skin_output_connections(SkinOutput *so,
SkinNode *skin_nodes,
const MEdge *medge,
- int totedge)
+ int edges_num)
{
int e;
- for (e = 0; e < totedge; e++) {
+ for (e = 0; e < edges_num; e++) {
SkinNode *a, *b;
a = &skin_nodes[medge[e].v1];
b = &skin_nodes[medge[e].v2];
@@ -1713,7 +1713,7 @@ static void skin_output_connections(SkinOutput *so,
static void skin_smooth_hulls(BMesh *bm,
SkinNode *skin_nodes,
- int totvert,
+ int verts_num,
const SkinModifierData *smd)
{
BMIter iter, eiter;
@@ -1726,7 +1726,7 @@ static void skin_smooth_hulls(BMesh *bm,
/* Mark all frame vertices */
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
- for (i = 0; i < totvert; i++) {
+ for (i = 0; i < verts_num; i++) {
for (j = 0; j < skin_nodes[i].totframe; j++) {
Frame *frame = &skin_nodes[i].frames[j];
@@ -1780,13 +1780,16 @@ static void skin_smooth_hulls(BMesh *bm,
}
/* Returns true if all hulls are successfully built, false otherwise */
-static bool skin_output_branch_hulls(
- SkinOutput *so, SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge)
+static bool skin_output_branch_hulls(SkinOutput *so,
+ SkinNode *skin_nodes,
+ int verts_num,
+ const MeshElemMap *emap,
+ const MEdge *medge)
{
bool result = true;
int v;
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
SkinNode *sn = &skin_nodes[v];
/* Branch node hulls */
@@ -1812,10 +1815,10 @@ typedef enum eSkinErrorFlag {
} eSkinErrorFlag;
static BMesh *build_skin(SkinNode *skin_nodes,
- int totvert,
+ int verts_num,
const MeshElemMap *emap,
const MEdge *medge,
- int totedge,
+ int edges_num,
const MDeformVert *input_dvert,
SkinModifierData *smd,
eSkinErrorFlag *r_error)
@@ -1841,19 +1844,19 @@ static BMesh *build_skin(SkinNode *skin_nodes,
/* Check for mergeable frame corners around hulls before
* outputting vertices */
- skin_merge_close_frame_verts(skin_nodes, totvert, emap, medge);
+ skin_merge_close_frame_verts(skin_nodes, verts_num, emap, medge);
/* Write out all frame vertices to the mesh */
- for (v = 0; v < totvert; v++) {
+ for (v = 0; v < verts_num; v++) {
if (skin_nodes[v].totframe) {
output_frames(so.bm, &skin_nodes[v], input_dvert ? &input_dvert[v] : NULL);
}
}
/* Update vertex pointers for merged frame corners */
- skin_update_merged_vertices(skin_nodes, totvert);
+ skin_update_merged_vertices(skin_nodes, verts_num);
- if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) {
+ if (!skin_output_branch_hulls(&so, skin_nodes, verts_num, emap, medge)) {
*r_error |= SKIN_ERROR_HULL;
}
@@ -1871,12 +1874,12 @@ static BMesh *build_skin(SkinNode *skin_nodes,
* creating all hull faces, but before creating any other
* faces.
*/
- skin_fix_hull_topology(so.bm, skin_nodes, totvert);
+ skin_fix_hull_topology(so.bm, skin_nodes, verts_num);
- skin_smooth_hulls(so.bm, skin_nodes, totvert, smd);
+ skin_smooth_hulls(so.bm, skin_nodes, verts_num, smd);
- skin_output_end_nodes(&so, skin_nodes, totvert);
- skin_output_connections(&so, skin_nodes, medge, totedge);
+ skin_output_end_nodes(&so, skin_nodes, verts_num);
+ skin_output_connections(&so, skin_nodes, medge, edges_num);
hull_merge_triangles(&so, smd);
bmesh_edit_end(so.bm, 0);
@@ -1912,7 +1915,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_
MVert *mvert;
MEdge *medge;
MDeformVert *dvert;
- int totvert, totedge;
+ int verts_num, edges_num;
bool has_valid_root = false;
nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN);
@@ -1920,17 +1923,17 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_
mvert = origmesh->mvert;
dvert = origmesh->dvert;
medge = origmesh->medge;
- totvert = origmesh->totvert;
- totedge = origmesh->totedge;
+ verts_num = origmesh->totvert;
+ edges_num = origmesh->totedge;
- BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, totvert, totedge);
+ BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, verts_num, edges_num);
- emat = build_edge_mats(nodes, mvert, totvert, medge, emap, totedge, &has_valid_root);
- skin_nodes = build_frames(mvert, totvert, nodes, emap, emat);
+ emat = build_edge_mats(nodes, mvert, verts_num, medge, emap, edges_num, &has_valid_root);
+ skin_nodes = build_frames(mvert, verts_num, nodes, emap, emat);
MEM_freeN(emat);
emat = NULL;
- bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd, r_error);
+ bm = build_skin(skin_nodes, verts_num, emap, medge, edges_num, dvert, smd, r_error);
MEM_freeN(skin_nodes);
MEM_freeN(emap);
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index 4236147c1f3..5439083d9a7 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -76,21 +76,21 @@ static void requiredDataMask(Object *UNUSED(ob),
}
static void smoothModifier_do(
- SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int numVerts)
+ SmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
{
if (mesh == NULL) {
return;
}
float(*accumulated_vecs)[3] = MEM_calloc_arrayN(
- (size_t)numVerts, sizeof(*accumulated_vecs), __func__);
+ (size_t)verts_num, sizeof(*accumulated_vecs), __func__);
if (!accumulated_vecs) {
return;
}
- uint *num_accumulated_vecs = MEM_calloc_arrayN(
- (size_t)numVerts, sizeof(*num_accumulated_vecs), __func__);
- if (!num_accumulated_vecs) {
+ uint *accumulated_vecs_count = MEM_calloc_arrayN(
+ (size_t)verts_num, sizeof(*accumulated_vecs_count), __func__);
+ if (!accumulated_vecs_count) {
MEM_freeN(accumulated_vecs);
return;
}
@@ -100,7 +100,7 @@ static void smoothModifier_do(
const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0;
MEdge *medges = mesh->medge;
- const int num_edges = mesh->totedge;
+ const int edges_num = mesh->totedge;
MDeformVert *dvert;
int defgrp_index;
@@ -108,31 +108,31 @@ static void smoothModifier_do(
for (int j = 0; j < smd->repeat; j++) {
if (j != 0) {
- memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * (size_t)numVerts);
- memset(num_accumulated_vecs, 0, sizeof(*num_accumulated_vecs) * (size_t)numVerts);
+ memset(accumulated_vecs, 0, sizeof(*accumulated_vecs) * (size_t)verts_num);
+ memset(accumulated_vecs_count, 0, sizeof(*accumulated_vecs_count) * (size_t)verts_num);
}
- for (int i = 0; i < num_edges; i++) {
+ for (int i = 0; i < edges_num; i++) {
float fvec[3];
const uint idx1 = medges[i].v1;
const uint idx2 = medges[i].v2;
mid_v3_v3v3(fvec, vertexCos[idx1], vertexCos[idx2]);
- num_accumulated_vecs[idx1]++;
+ accumulated_vecs_count[idx1]++;
add_v3_v3(accumulated_vecs[idx1], fvec);
- num_accumulated_vecs[idx2]++;
+ accumulated_vecs_count[idx2]++;
add_v3_v3(accumulated_vecs[idx2], fvec);
}
const short flag = smd->flag;
if (dvert) {
MDeformVert *dv = dvert;
- for (int i = 0; i < numVerts; i++, dv++) {
+ for (int i = 0; i < verts_num; i++, dv++) {
float *vco_orig = vertexCos[i];
- if (num_accumulated_vecs[i] > 0) {
- mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]);
+ if (accumulated_vecs_count[i] > 0) {
+ mul_v3_fl(accumulated_vecs[i], 1.0f / (float)accumulated_vecs_count[i]);
}
float *vco_new = accumulated_vecs[i];
@@ -156,10 +156,10 @@ static void smoothModifier_do(
}
}
else { /* no vertex group */
- for (int i = 0; i < numVerts; i++) {
+ for (int i = 0; i < verts_num; i++) {
float *vco_orig = vertexCos[i];
- if (num_accumulated_vecs[i] > 0) {
- mul_v3_fl(accumulated_vecs[i], 1.0f / (float)num_accumulated_vecs[i]);
+ if (accumulated_vecs_count[i] > 0) {
+ mul_v3_fl(accumulated_vecs[i], 1.0f / (float)accumulated_vecs_count[i]);
}
float *vco_new = accumulated_vecs[i];
@@ -177,22 +177,22 @@ static void smoothModifier_do(
}
MEM_freeN(accumulated_vecs);
- MEM_freeN(num_accumulated_vecs);
+ MEM_freeN(accumulated_vecs_count);
}
static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
Mesh *mesh_src = NULL;
/* mesh_src is needed for vgroups, and taking edges into account. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
- smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
+ smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -204,18 +204,18 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SmoothModifierData *smd = (SmoothModifierData *)md;
Mesh *mesh_src = NULL;
/* mesh_src is needed for vgroups, and taking edges into account. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false, false);
/* TODO(campbell): use edit-mode data only (remove this line). */
BKE_mesh_wrapper_ensure_mdata(mesh_src);
- smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, numVerts);
+ smoothModifier_do(smd, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index ae90240dd3f..d43e26f25e1 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -40,11 +40,11 @@ static void deformVerts(ModifierData *UNUSED(md),
const ModifierEvalContext *ctx,
Mesh *UNUSED(derivedData),
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
sbObjectStep(
- ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, numVerts);
+ ctx->depsgraph, scene, ctx->object, DEG_get_ctime(ctx->depsgraph), vertexCos, verts_num);
}
static bool dependsOnTime(struct Scene *UNUSED(scene),
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index fdaf7bd41d1..80af23054e4 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -55,14 +55,14 @@ BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref)
*/
static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (*r_vert_nors)[3])
{
- int i, numVerts, numEdges, numPolys;
+ int i, verts_num, edges_num, polys_num;
MPoly *mpoly, *mp;
MLoop *mloop, *ml;
MEdge *medge, *ed;
- numVerts = mesh->totvert;
- numEdges = mesh->totedge;
- numPolys = mesh->totpoly;
+ verts_num = mesh->totvert;
+ edges_num = mesh->totedge;
+ polys_num = mesh->totpoly;
mpoly = mesh->mpoly;
medge = mesh->medge;
mloop = mesh->mloop;
@@ -71,7 +71,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (
/* Doesn't work here! */
#if 0
- mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
+ mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, verts_num);
cddm->mvert = mv;
#endif
@@ -79,12 +79,12 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (
{
EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN(
- (size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
+ (size_t)edges_num, sizeof(EdgeFaceRef), "Edge Connectivity");
EdgeFaceRef *edge_ref;
float edge_normal[3];
/* Add an edge reference if it's not there, pointing back to the face index. */
- for (i = 0; i < numPolys; i++, mp++) {
+ for (i = 0; i < polys_num; i++, mp++) {
int j;
ml = mloop + mp->loopstart;
@@ -110,7 +110,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (
}
}
- for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
+ for (i = 0, ed = medge, edge_ref = edge_ref_array; i < edges_num; i++, ed++, edge_ref++) {
/* Get the edge vert indices, and edge value (the face indices that use it) */
if (edgeref_is_init(edge_ref) && (edge_ref->p1 != -1)) {
@@ -141,7 +141,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const float (*poly_nors)[3], float (
/* normalize vertex normals and assign */
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
if (normalize_v3(r_vert_nors[i]) == 0.0f) {
copy_v3_v3(r_vert_nors[i], vert_normals[i]);
}
@@ -164,10 +164,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
MEdge *ed, *medge, *orig_medge;
MLoop *ml, *mloop, *orig_mloop;
MPoly *mp, *mpoly, *orig_mpoly;
- const uint numVerts = (uint)mesh->totvert;
- const uint numEdges = (uint)mesh->totedge;
- const uint numPolys = (uint)mesh->totpoly;
- const uint numLoops = (uint)mesh->totloop;
+ const uint verts_num = (uint)mesh->totvert;
+ const uint edges_num = (uint)mesh->totedge;
+ const uint polys_num = (uint)mesh->totpoly;
+ const uint loops_num = (uint)mesh->totloop;
uint newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0;
/* Only use material offsets if we have 2 or more materials. */
@@ -184,7 +184,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
STACK_DECLARE(new_edge_arr);
uint *old_vert_arr = MEM_calloc_arrayN(
- numVerts, sizeof(*old_vert_arr), "old_vert_arr in solidify");
+ verts_num, sizeof(*old_vert_arr), "old_vert_arr in solidify");
uint *edge_users = NULL;
int *edge_order = NULL;
@@ -233,33 +233,34 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
poly_nors = BKE_mesh_poly_normals_ensure(mesh);
}
- STACK_INIT(new_vert_arr, numVerts * 2);
- STACK_INIT(new_edge_arr, numEdges * 2);
+ STACK_INIT(new_vert_arr, verts_num * 2);
+ STACK_INIT(new_edge_arr, edges_num * 2);
if (do_rim) {
- BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(numVerts, __func__);
+ BLI_bitmap *orig_mvert_tag = BLI_BITMAP_NEW(verts_num, __func__);
uint eidx;
uint i;
#define INVALID_UNUSED ((uint)-1)
#define INVALID_PAIR ((uint)-2)
- new_vert_arr = MEM_malloc_arrayN(numVerts, 2 * sizeof(*new_vert_arr), __func__);
- new_edge_arr = MEM_malloc_arrayN(((numEdges * 2) + numVerts), sizeof(*new_edge_arr), __func__);
+ new_vert_arr = MEM_malloc_arrayN(verts_num, 2 * sizeof(*new_vert_arr), __func__);
+ new_edge_arr = MEM_malloc_arrayN(
+ ((edges_num * 2) + verts_num), 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 order");
+ edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges");
+ edge_order = MEM_malloc_arrayN(edges_num, sizeof(*edge_order), "solid_mod order");
/* save doing 2 loops here... */
#if 0
- copy_vn_i(edge_users, numEdges, INVALID_UNUSED);
+ copy_vn_i(edge_users, edges_num, INVALID_UNUSED);
#endif
- for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
+ for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) {
edge_users[eidx] = INVALID_UNUSED;
}
- for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) {
+ for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) {
MLoop *ml_prev;
int j;
@@ -272,7 +273,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (edge_users[eidx] == INVALID_UNUSED) {
ed = orig_medge + eidx;
BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2));
- edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + numPolys);
+ edge_users[eidx] = (ml_prev->v > ml->v) == (ed->v1 < ed->v2) ? i : (i + polys_num);
edge_order[eidx] = j;
}
else {
@@ -282,7 +283,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
}
- for (eidx = 0, ed = orig_medge; eidx < numEdges; eidx++, ed++) {
+ for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) {
if (!ELEM(edge_users[eidx], INVALID_UNUSED, INVALID_PAIR)) {
BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v1);
BLI_BITMAP_ENABLE(orig_mvert_tag, ed->v2);
@@ -292,7 +293,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
}
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
if (BLI_BITMAP_TEST(orig_mvert_tag, i)) {
old_vert_arr[i] = STACK_SIZE(new_vert_arr);
STACK_PUSH(new_vert_arr, i);
@@ -319,16 +320,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
- vert_nors = MEM_calloc_arrayN(numVerts, sizeof(float[3]), "mod_solid_vno_hq");
+ vert_nors = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno_hq");
mesh_calc_hq_normal(mesh, poly_nors, vert_nors);
}
result = BKE_mesh_new_nomain_from_template(mesh,
- (int)((numVerts * stride) + newVerts),
- (int)((numEdges * stride) + newEdges + rimVerts),
+ (int)((verts_num * stride) + newVerts),
+ (int)((edges_num * stride) + newEdges + rimVerts),
0,
- (int)((numLoops * stride) + newLoops),
- (int)((numPolys * stride) + newPolys));
+ (int)((loops_num * stride) + newLoops),
+ (int)((polys_num * stride) + newPolys));
mpoly = result->mpoly;
mloop = result->mloop;
@@ -341,69 +342,69 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (do_shell) {
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)numVerts, (int)numVerts);
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num);
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)verts_num, (int)verts_num);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
- CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)numEdges, (int)numEdges);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)edges_num, (int)edges_num);
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num);
/* DO NOT copy here the 'copied' part of loop data, we want to reverse loops
* (so that winding of copied face get reversed, so that normals get reversed
* and point in expected direction...).
* If we also copy data here, then this data get overwritten
* (and allocated memory becomes memleak). */
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)numPolys, (int)numPolys);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)polys_num, (int)polys_num);
}
else {
int i, j;
- CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)numVerts);
- for (i = 0, j = (int)numVerts; i < numVerts; i++) {
+ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num);
+ for (i = 0, j = (int)verts_num; i < verts_num; i++) {
if (old_vert_arr[i] != INVALID_UNUSED) {
CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1);
j++;
}
}
- CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)numEdges);
+ CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num);
- for (i = 0, j = (int)numEdges; i < numEdges; i++) {
+ for (i = 0, j = (int)edges_num; i < edges_num; i++) {
if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) {
MEdge *ed_src, *ed_dst;
CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1);
ed_src = &medge[i];
ed_dst = &medge[j];
- ed_dst->v1 = old_vert_arr[ed_src->v1] + numVerts;
- ed_dst->v2 = old_vert_arr[ed_src->v2] + numVerts;
+ ed_dst->v1 = old_vert_arr[ed_src->v1] + verts_num;
+ ed_dst->v2 = old_vert_arr[ed_src->v2] + verts_num;
j++;
}
}
/* will be created later */
- CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)numLoops);
- CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)numPolys);
+ CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num);
+ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num);
}
/* initializes: (i_end, do_shell_align, mv). */
#define INIT_VERT_ARRAY_OFFSETS(test) \
if (((ofs_new >= ofs_orig) == do_flip) == test) { \
- i_end = numVerts; \
+ i_end = verts_num; \
do_shell_align = true; \
mv = mvert; \
} \
else { \
if (do_shell) { \
- i_end = numVerts; \
+ i_end = verts_num; \
do_shell_align = true; \
} \
else { \
i_end = newVerts; \
do_shell_align = false; \
} \
- mv = &mvert[numVerts]; \
+ mv = &mvert[verts_num]; \
} \
(void)0
@@ -412,7 +413,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (do_shell) {
uint i;
- mp = mpoly + numPolys;
+ mp = mpoly + polys_num;
for (i = 0; i < mesh->totpoly; i++, mp++) {
const int loop_end = mp->totloop - 1;
MLoop *ml2;
@@ -457,14 +458,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
mp->loopstart += mesh->totloop;
for (j = 0; j < mp->totloop; j++) {
- ml2[j].e += numEdges;
- ml2[j].v += numVerts;
+ ml2[j].e += edges_num;
+ ml2[j].v += verts_num;
}
}
- for (i = 0, ed = medge + numEdges; i < numEdges; i++, ed++) {
- ed->v1 += numVerts;
- ed->v2 += numVerts;
+ for (i = 0, ed = medge + edges_num; i < edges_num; i++, ed++) {
+ ed->v1 += verts_num;
+ ed->v2 += verts_num;
}
}
@@ -483,9 +484,9 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
float *edge_angs = NULL;
if (do_clamp) {
- vert_lens = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens");
- copy_vn_fl(vert_lens, (int)numVerts, FLT_MAX);
- for (uint i = 0; i < numEdges; i++) {
+ vert_lens = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens");
+ copy_vn_fl(vert_lens, (int)verts_num, FLT_MAX);
+ for (uint i = 0; i < edges_num; i++) {
const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq);
vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq);
@@ -495,23 +496,23 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (do_angle_clamp || do_bevel_convex) {
uint eidx;
if (do_angle_clamp) {
- vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs");
- copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI);
+ vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs");
+ copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI);
}
if (do_bevel_convex) {
- edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs");
+ edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs");
if (!do_rim) {
- edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges");
+ edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges");
}
}
uint(*edge_user_pairs)[2] = MEM_malloc_arrayN(
- numEdges, sizeof(*edge_user_pairs), "edge_user_pairs");
- for (eidx = 0; eidx < numEdges; eidx++) {
+ edges_num, sizeof(*edge_user_pairs), "edge_user_pairs");
+ for (eidx = 0; eidx < edges_num; eidx++) {
edge_user_pairs[eidx][0] = INVALID_UNUSED;
edge_user_pairs[eidx][1] = INVALID_UNUSED;
}
mp = orig_mpoly;
- for (uint i = 0; i < numPolys; i++, mp++) {
+ for (uint i = 0; i < polys_num; i++, mp++) {
ml = orig_mloop + mp->loopstart;
MLoop *ml_prev = ml + (mp->totloop - 1);
@@ -533,7 +534,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
ed = orig_medge;
float e[3];
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) &&
!ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) {
const float *n0 = poly_nors[edge_user_pairs[i][0]];
@@ -658,7 +659,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (do_bevel_convex) {
- for (uint i = 0; i < numEdges; i++) {
+ for (uint i = 0; i < edges_num; i++) {
if (edge_users[i] == INVALID_PAIR) {
float angle = edge_angs[i];
medge[i].bweight = (char)clamp_i(
@@ -668,8 +669,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
0,
255);
if (do_shell) {
- medge[i + numEdges].bweight = (char)clamp_i(
- (int)medge[i + numEdges].bweight +
+ medge[i + edges_num].bweight = (char)clamp_i(
+ (int)medge[i + edges_num].bweight +
(int)((angle > M_PI ? clamp_f(bevel_convex, 0.0f, 1.0f) :
clamp_f(bevel_convex, -1.0f, 0.0f)) *
255),
@@ -697,19 +698,19 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
#endif
/* same as EM_solidify() in editmesh_lib.c */
float *vert_angles = MEM_calloc_arrayN(
- numVerts, sizeof(float[2]), "mod_solid_pair"); /* 2 in 1 */
- float *vert_accum = vert_angles + numVerts;
+ verts_num, sizeof(float[2]), "mod_solid_pair"); /* 2 in 1 */
+ float *vert_accum = vert_angles + verts_num;
uint vidx;
uint i;
if (vert_nors == NULL) {
- vert_nors = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "mod_solid_vno");
- for (i = 0, mv = mvert; i < numVerts; i++, mv++) {
+ vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno");
+ for (i = 0, mv = mvert; i < verts_num; i++, mv++) {
copy_v3_v3(vert_nors[i], mesh_vert_normals[i]);
}
}
- for (i = 0, mp = mpoly; i < numPolys; i++, mp++) {
+ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
/* #BKE_mesh_calc_poly_angles logic is inlined here */
float nor_prev[3];
float nor_next[3];
@@ -765,14 +766,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
float scalar;
if (defgrp_invert) {
- for (i = 0; i < numVerts; i++, dv++) {
+ for (i = 0; i < verts_num; i++, dv++) {
scalar = 1.0f - BKE_defvert_find_weight(dv, defgrp_index);
scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
vert_angles[i] *= scalar;
}
}
else {
- for (i = 0; i < numVerts; i++, dv++) {
+ for (i = 0; i < verts_num; i++, dv++) {
scalar = BKE_defvert_find_weight(dv, defgrp_index);
scalar = offset_fac_vg + (scalar * offset_fac_vg_inv);
vert_angles[i] *= scalar;
@@ -788,22 +789,22 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (do_angle_clamp || do_bevel_convex) {
uint eidx;
if (do_angle_clamp) {
- vert_angs = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_angs even");
- copy_vn_fl(vert_angs, (int)numVerts, 0.5f * M_PI);
+ vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs even");
+ copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI);
}
if (do_bevel_convex) {
- edge_angs = MEM_malloc_arrayN(numEdges, sizeof(float), "edge_angs even");
+ edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs even");
if (!do_rim) {
- edge_users = MEM_malloc_arrayN(numEdges, sizeof(*edge_users), "solid_mod edges");
+ edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges");
}
}
uint(*edge_user_pairs)[2] = MEM_malloc_arrayN(
- numEdges, sizeof(*edge_user_pairs), "edge_user_pairs");
- for (eidx = 0; eidx < numEdges; eidx++) {
+ edges_num, sizeof(*edge_user_pairs), "edge_user_pairs");
+ for (eidx = 0; eidx < edges_num; eidx++) {
edge_user_pairs[eidx][0] = INVALID_UNUSED;
edge_user_pairs[eidx][1] = INVALID_UNUSED;
}
- for (i = 0, mp = orig_mpoly; i < numPolys; i++, mp++) {
+ for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) {
ml = orig_mloop + mp->loopstart;
MLoop *ml_prev = ml + (mp->totloop - 1);
@@ -825,7 +826,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
ed = orig_medge;
float e[3];
- for (i = 0; i < numEdges; i++, ed++) {
+ for (i = 0; i < edges_num; i++, ed++) {
if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) &&
!ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) {
const float *n0 = poly_nors[edge_user_pairs[i][0]];
@@ -852,16 +853,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
const float clamp_fac = 1 + (do_angle_clamp ? fabsf(smd->offset_fac) : 0);
const float offset = fabsf(smd->offset) * smd->offset_clamp * clamp_fac;
if (offset > FLT_EPSILON) {
- float *vert_lens_sq = MEM_malloc_arrayN(numVerts, sizeof(float), "vert_lens_sq");
+ float *vert_lens_sq = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens_sq");
const float offset_sq = offset * offset;
- copy_vn_fl(vert_lens_sq, (int)numVerts, FLT_MAX);
- for (i = 0; i < numEdges; i++) {
+ copy_vn_fl(vert_lens_sq, (int)verts_num, FLT_MAX);
+ for (i = 0; i < edges_num; i++) {
const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len);
vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len);
}
if (do_angle_clamp) {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float cos_ang = cosf(vert_angs[i] * 0.5f);
if (cos_ang > 0) {
float max_off = sqrtf(vert_lens_sq[i]) * 0.5f / cos_ang;
@@ -873,7 +874,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
MEM_freeN(vert_angs);
}
else {
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
if (vert_lens_sq[i] < offset_sq) {
float scalar = sqrtf(vert_lens_sq[i]) / offset;
vert_angles[i] *= scalar;
@@ -885,7 +886,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
if (do_bevel_convex) {
- for (i = 0; i < numEdges; i++) {
+ for (i = 0; i < edges_num; i++) {
if (edge_users[i] == INVALID_PAIR) {
float angle = edge_angs[i];
medge[i].bweight = (char)clamp_i(
@@ -895,8 +896,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
0,
255);
if (do_shell) {
- medge[i + numEdges].bweight = (char)clamp_i(
- (int)medge[i + numEdges].bweight +
+ medge[i + edges_num].bweight = (char)clamp_i(
+ (int)medge[i + edges_num].bweight +
(int)((angle > M_PI ? clamp_f(bevel_convex, 0, 1) :
clamp_f(bevel_convex, -1, 0)) *
255),
@@ -959,8 +960,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
else if (do_shell) {
uint i;
/* flip vertex normals for copied verts */
- mv = mvert + numVerts;
- for (i = 0; i < numVerts; i++) {
+ mv = mvert + verts_num;
+ for (i = 0; i < verts_num; i++) {
negate_v3((float *)mesh_vert_normals[i]);
}
}
@@ -982,14 +983,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
for (uint i = 0; i < rimVerts; i++) {
BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight =
1.0f;
- BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + numVerts],
+ BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + verts_num],
rim_defgrp_index)
->weight = 1.0f;
}
}
if (shell_defgrp_index != -1) {
- for (uint i = numVerts; i < result->totvert; i++) {
+ for (uint i = verts_num; i < result->totvert; i++) {
BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f;
}
}
@@ -1014,7 +1015,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
const bool do_side_normals = !BKE_mesh_vertex_normals_are_dirty(result);
/* annoying to allocate these since we only need the edge verts, */
float(*edge_vert_nos)[3] = do_side_normals ?
- MEM_calloc_arrayN(numVerts, sizeof(float[3]), __func__) :
+ MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__) :
NULL;
float nor[3];
#endif
@@ -1032,11 +1033,11 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* add faces & edges */
origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX);
- orig_ed = (origindex_edge) ? &origindex_edge[(numEdges * stride) + newEdges] : NULL;
- ed = &medge[(numEdges * stride) + newEdges]; /* start after copied edges */
+ orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL;
+ ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */
for (i = 0; i < rimVerts; i++, ed++) {
ed->v1 = new_vert_arr[i];
- ed->v2 = (do_shell ? new_vert_arr[i] : i) + numVerts;
+ ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num;
ed->flag |= ME_EDGEDRAW | ME_EDGERENDER;
if (orig_ed) {
@@ -1050,8 +1051,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
}
/* faces */
- mp = mpoly + (numPolys * stride);
- ml = mloop + (numLoops * stride);
+ mp = mpoly + (polys_num * stride);
+ ml = mloop + (loops_num * stride);
j = 0;
for (i = 0; i < newPolys; i++, mp++) {
uint eidx = new_edge_arr[i];
@@ -1059,8 +1060,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
int k1, k2;
bool flip;
- if (pidx >= numPolys) {
- pidx -= numPolys;
+ if (pidx >= polys_num) {
+ pidx -= polys_num;
flip = true;
}
else {
@@ -1071,8 +1072,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
/* copy most of the face settings */
CustomData_copy_data(
- &mesh->pdata, &result->pdata, (int)pidx, (int)((numPolys * stride) + i), 1);
- mp->loopstart = (int)(j + (numLoops * stride));
+ &mesh->pdata, &result->pdata, (int)pidx, (int)((polys_num * stride) + i), 1);
+ mp->loopstart = (int)(j + (loops_num * stride));
mp->flag = mpoly[pidx].flag;
/* notice we use 'mp->totloop' which is later overwritten,
@@ -1087,39 +1088,39 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
mp->totloop = 4;
CustomData_copy_data(
- &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 0), 1);
+ &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 0), 1);
CustomData_copy_data(
- &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 1), 1);
+ &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 1), 1);
CustomData_copy_data(
- &mesh->ldata, &result->ldata, k1, (int)((numLoops * stride) + j + 2), 1);
+ &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 2), 1);
CustomData_copy_data(
- &mesh->ldata, &result->ldata, k2, (int)((numLoops * stride) + j + 3), 1);
+ &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 3), 1);
if (flip == false) {
ml[j].v = ed->v1;
ml[j++].e = eidx;
ml[j].v = ed->v2;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
+ ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v2] + newEdges;
- ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
- ml[j++].e = (do_shell ? eidx : i) + numEdges;
+ ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + verts_num;
+ ml[j++].e = (do_shell ? eidx : i) + edges_num;
- ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
+ ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + verts_num;
+ ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v1] + newEdges;
}
else {
ml[j].v = ed->v2;
ml[j++].e = eidx;
ml[j].v = ed->v1;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v1] + newEdges;
+ ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v1] + newEdges;
- ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + numVerts;
- ml[j++].e = (do_shell ? eidx : i) + numEdges;
+ ml[j].v = (do_shell ? ed->v1 : old_vert_arr[ed->v1]) + verts_num;
+ ml[j++].e = (do_shell ? eidx : i) + edges_num;
- ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + numVerts;
- ml[j++].e = (numEdges * stride) + old_vert_arr[ed->v2] + newEdges;
+ ml[j].v = (do_shell ? ed->v2 : old_vert_arr[ed->v2]) + verts_num;
+ ml[j++].e = (edges_num * stride) + old_vert_arr[ed->v2] + newEdges;
}
if (origindex_edge) {
@@ -1141,7 +1142,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
if (crease_inner) {
/* crease += crease_inner; without wrapping */
- char *cr = &(medge[numEdges + (do_shell ? eidx : i)].crease);
+ char *cr = &(medge[edges_num + (do_shell ? eidx : i)].crease);
int tcr = *cr + crease_inner;
*cr = tcr > 255 ? 255 : tcr;
}
@@ -1163,13 +1164,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
#ifdef SOLIDIFY_SIDE_NORMALS
if (do_side_normals) {
const MEdge *ed_orig = medge;
- ed = medge + (numEdges * stride);
+ ed = medge + (edges_num * stride);
for (i = 0; i < rimVerts; i++, ed++, ed_orig++) {
float nor_cpy[3];
int k;
/* NOTE: only the first vertex (lower half of the index) is calculated. */
- BLI_assert(ed->v1 < numVerts);
+ BLI_assert(ed->v1 < verts_num);
normalize_v3_v3(nor_cpy, edge_vert_nos[ed_orig->v1]);
for (k = 0; k < 2; k++) { /* loop over both verts of the edge */
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index ff25c1afd49..8a84cd0a3bf 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -141,11 +141,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEdge *ed, *medge, *orig_medge;
MLoop *ml, *mloop, *orig_mloop;
MPoly *mp, *mpoly, *orig_mpoly;
- const uint numVerts = (uint)mesh->totvert;
- const uint numEdges = (uint)mesh->totedge;
- const uint numPolys = (uint)mesh->totpoly;
+ const uint verts_num = (uint)mesh->totvert;
+ const uint edges_num = (uint)mesh->totedge;
+ const uint polys_num = (uint)mesh->totpoly;
- if (numPolys == 0 && numVerts != 0) {
+ if (polys_num == 0 && verts_num != 0) {
return mesh;
}
@@ -193,28 +193,28 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
orig_mloop = mesh->mloop;
orig_mpoly = mesh->mpoly;
- uint numNewVerts = 0;
- uint numNewEdges = 0;
- uint numNewLoops = 0;
- uint numNewPolys = 0;
+ uint new_verts_num = 0;
+ uint new_edges_num = 0;
+ uint new_loops_num = 0;
+ uint new_polys_num = 0;
#define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1)
/* Calculate only face normals. Copied because they are modified directly below. */
- float(*poly_nors)[3] = MEM_malloc_arrayN(numPolys, sizeof(float[3]), __func__);
- memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * numPolys);
+ float(*poly_nors)[3] = MEM_malloc_arrayN(polys_num, sizeof(float[3]), __func__);
+ memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * polys_num);
NewFaceRef *face_sides_arr = MEM_malloc_arrayN(
- numPolys * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify");
+ polys_num * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify");
bool *null_faces =
(smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) ?
- MEM_calloc_arrayN(numPolys, sizeof(*null_faces), "null_faces in solidify") :
+ MEM_calloc_arrayN(polys_num, sizeof(*null_faces), "null_faces in solidify") :
NULL;
uint largest_ngon = 3;
/* Calculate face to #NewFaceRef map. */
{
mp = orig_mpoly;
- for (uint i = 0; i < numPolys; i++, mp++) {
+ for (uint i = 0; i < polys_num; i++, mp++) {
/* Make normals for faces without area (should really be avoided though). */
if (len_squared_v3(poly_nors[i]) < 0.5f) {
MEdge *e = orig_medge + orig_mloop[mp->loopstart].e;
@@ -244,18 +244,18 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
/* add to final mesh face count */
if (do_shell) {
- numNewPolys += 2;
- numNewLoops += (uint)mp->totloop * 2;
+ new_polys_num += 2;
+ new_loops_num += (uint)mp->totloop * 2;
}
}
}
uint *edge_adj_faces_len = MEM_calloc_arrayN(
- numEdges, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify");
+ edges_num, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify");
/* Count for each edge how many faces it has adjacent. */
{
mp = orig_mpoly;
- for (uint i = 0; i < numPolys; i++, mp++) {
+ for (uint i = 0; i < polys_num; i++, mp++) {
ml = orig_mloop + mp->loopstart;
for (uint j = 0; j < mp->totloop; j++, ml++) {
edge_adj_faces_len[ml->e]++;
@@ -265,16 +265,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Original edge to #NewEdgeRef map. */
NewEdgeRef ***orig_edge_data_arr = MEM_calloc_arrayN(
- numEdges, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify");
+ edges_num, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify");
/* Original edge length cache. */
float *orig_edge_lengths = MEM_calloc_arrayN(
- numEdges, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify");
+ edges_num, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify");
/* Edge groups for every original vert. */
EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN(
- numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify");
+ verts_num, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify");
/* vertex map used to map duplicates. */
- uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify");
- for (uint i = 0; i < numVerts; i++) {
+ uint *vm = MEM_malloc_arrayN(verts_num, sizeof(*vm), "orig_vert_map in solidify");
+ for (uint i = 0; i < verts_num; i++) {
vm[i] = i;
}
@@ -286,12 +286,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Vert edge adjacent map. */
OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN(
- numVerts, sizeof(*vert_adj_edges), "vert_adj_edges in solidify");
+ verts_num, sizeof(*vert_adj_edges), "vert_adj_edges in solidify");
/* Original vertex positions (changed for degenerated geometry). */
float(*orig_mvert_co)[3] = MEM_malloc_arrayN(
- numVerts, sizeof(*orig_mvert_co), "orig_mvert_co in solidify");
+ verts_num, sizeof(*orig_mvert_co), "orig_mvert_co in solidify");
/* Fill in the original vertex positions. */
- for (uint i = 0; i < numVerts; i++) {
+ for (uint i = 0; i < verts_num; i++) {
orig_mvert_co[i][0] = orig_mvert[i].co[0];
orig_mvert_co[i][1] = orig_mvert[i].co[1];
orig_mvert_co[i][2] = orig_mvert[i].co[2];
@@ -300,12 +300,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create edge to #NewEdgeRef map. */
{
OldEdgeFaceRef **edge_adj_faces = MEM_calloc_arrayN(
- numEdges, sizeof(*edge_adj_faces), "edge_adj_faces in solidify");
+ edges_num, sizeof(*edge_adj_faces), "edge_adj_faces in solidify");
/* Create link_faces for edges. */
{
mp = orig_mpoly;
- for (uint i = 0; i < numPolys; i++, mp++) {
+ for (uint i = 0; i < polys_num; i++, mp++) {
ml = orig_mloop + mp->loopstart;
for (uint j = 0; j < mp->totloop; j++, ml++) {
const uint edge = ml->e;
@@ -342,19 +342,19 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
float edgedir[3] = {0, 0, 0};
uint *vert_adj_edges_len = MEM_calloc_arrayN(
- numVerts, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify");
+ verts_num, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify");
/* Calculate edge lengths and len vert_adj edges. */
{
bool *face_singularity = MEM_calloc_arrayN(
- numPolys, sizeof(*face_singularity), "face_sides_arr in solidify");
+ polys_num, sizeof(*face_singularity), "face_sides_arr in solidify");
const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance;
uint *combined_verts = MEM_calloc_arrayN(
- numVerts, sizeof(*combined_verts), "combined_verts in solidify");
+ verts_num, sizeof(*combined_verts), "combined_verts in solidify");
ed = orig_medge;
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
if (edge_adj_faces_len[i] > 0) {
uint v1 = vm[ed->v1];
uint v2 = vm[ed->v2];
@@ -373,7 +373,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* This check is very slow. It would need the vertex edge links to get
* accelerated that are not yet available at this point. */
bool can_merge = true;
- for (uint k = 0; k < numEdges && can_merge; k++) {
+ for (uint k = 0; k < edges_num && can_merge; k++) {
if (k != i && edge_adj_faces_len[k] > 0 &&
(ELEM(vm[orig_medge[k].v1], v1, v2) != ELEM(vm[orig_medge[k].v2], v1, v2))) {
for (uint j = 0; j < edge_adj_faces[k]->faces_len && can_merge; j++) {
@@ -402,7 +402,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
(combined_verts[v2] + 1) /
(float)(combined_verts[v1] + combined_verts[v2] + 2));
add_v3_v3(orig_mvert_co[v1], edgedir);
- for (uint j = v2; j < numVerts; j++) {
+ for (uint j = v2; j < verts_num; j++) {
if (vm[j] == v2) {
vm[j] = v1;
}
@@ -412,7 +412,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
combined_verts[v1] += combined_verts[v2] + 1;
if (do_shell) {
- numNewLoops -= edge_adj_faces_len[i] * 2;
+ new_loops_num -= edge_adj_faces_len[i] * 2;
}
edge_adj_faces_len[i] = 0;
@@ -430,7 +430,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
/* remove zero faces in a second pass */
ed = orig_medge;
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
const uint v1 = vm[ed->v1];
const uint v2 = vm[ed->v2];
if (v1 == v2 && edge_adj_faces[i]) {
@@ -449,14 +449,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
face_singularity[face] = true;
/* remove from final mesh poly count */
if (do_shell) {
- numNewPolys -= 2;
+ new_polys_num -= 2;
}
}
}
}
if (do_shell) {
- numNewLoops -= edge_adj_faces_len[i] * 2;
+ new_loops_num -= edge_adj_faces_len[i] * 2;
}
edge_adj_faces_len[i] = 0;
@@ -474,7 +474,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create vert_adj_edges for verts. */
{
ed = orig_medge;
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
if (edge_adj_faces_len[i] > 0) {
const uint vs[2] = {vm[ed->v1], vm[ed->v2]};
uint invalid_edge_index = 0;
@@ -545,8 +545,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
/* remove from final face count */
if (do_shell) {
- numNewPolys -= 2 * j;
- numNewLoops -= 4 * j;
+ new_polys_num -= 2 * j;
+ new_loops_num -= 4 * j;
}
const uint len = i_adj_faces->faces_len + invalid_adj_faces->faces_len - 2 * j;
uint *adj_faces = MEM_malloc_arrayN(
@@ -595,7 +595,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
ed = orig_medge;
/* Iterate over edges and only check the faces around an edge for duplicates
* (performance optimization). */
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
if (edge_adj_faces_len[i] > 0) {
const OldEdgeFaceRef *adj_faces = edge_adj_faces[i];
uint adj_len = adj_faces->faces_len;
@@ -674,7 +674,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
else if (e_adj_faces->used > 1) {
- for (uint n = 0; n < numEdges; n++) {
+ for (uint n = 0; n < edges_num; n++) {
if (edge_adj_faces[n] == e_adj_faces && edge_adj_faces_len[n] > 0) {
edge_adj_faces_len[n]--;
if (edge_adj_faces_len[n] == 0) {
@@ -689,8 +689,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
if (do_shell) {
- numNewPolys -= 2;
- numNewLoops -= 2 * (uint)del_loops;
+ new_polys_num -= 2;
+ new_loops_num -= 2 * (uint)del_loops;
}
break;
}
@@ -704,7 +704,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create #NewEdgeRef array. */
{
ed = orig_medge;
- for (uint i = 0; i < numEdges; i++, ed++) {
+ for (uint i = 0; i < edges_num; i++, ed++) {
const uint v1 = vm[ed->v1];
const uint v2 = vm[ed->v2];
if (edge_adj_faces_len[i] > 0) {
@@ -807,8 +807,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
(adj_faces_reversed[0] ? 1 : 0);
if (do_rim) {
/* Only add the loops parallel to the edge for now. */
- numNewLoops += 2;
- numNewPolys++;
+ new_loops_num += 2;
+ new_polys_num++;
}
}
@@ -864,13 +864,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(sorted_faces);
orig_edge_data_arr[i] = new_edges;
if (do_shell || (adj_len == 1 && do_rim)) {
- numNewEdges += new_edges_len;
+ new_edges_num += new_edges_len;
}
}
}
}
- for (uint i = 0; i < numEdges; i++) {
+ for (uint i = 0; i < edges_num; i++) {
if (edge_adj_faces[i]) {
if (edge_adj_faces[i]->used > 1) {
edge_adj_faces[i]->used--;
@@ -888,7 +888,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Create sorted edge groups for every vert. */
{
OldVertEdgeRef **adj_edges_ptr = vert_adj_edges;
- for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) {
+ for (uint i = 0; i < verts_num; i++, adj_edges_ptr++) {
if (*adj_edges_ptr != NULL && (*adj_edges_ptr)->edges_len >= 2) {
EdgeGroup *edge_groups;
@@ -1305,7 +1305,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
uint added = 0;
if (do_shell || (do_rim && !g->is_orig_closed)) {
BLI_assert(g->new_vert == MOD_SOLIDIFY_EMPTY_TAG);
- g->new_vert = numNewVerts++;
+ g->new_vert = new_verts_num++;
if (do_rim || (do_shell && g->split)) {
new_verts++;
contains_splits += (g->split != 0);
@@ -1321,23 +1321,23 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
last_added = added;
if (!(g + 1)->valid || g->topo_group != (g + 1)->topo_group) {
if (new_verts > 2) {
- numNewPolys++;
- numNewEdges += new_verts;
+ new_polys_num++;
+ new_edges_num += new_verts;
open_edges += (uint)(first_added < last_added);
open_edges -= (uint)(open_edges && !contains_open_splits);
if (do_shell && do_rim) {
- numNewLoops += new_verts * 2;
+ new_loops_num += new_verts * 2;
}
else if (do_shell) {
- numNewLoops += new_verts * 2 - open_edges;
+ new_loops_num += new_verts * 2 - open_edges;
}
else { // do_rim
- numNewLoops += new_verts * 2 + open_edges - contains_splits;
+ new_loops_num += new_verts * 2 + open_edges - contains_splits;
}
}
else if (new_verts == 2) {
- numNewEdges++;
- numNewLoops += 2u - (uint)(!(do_rim && do_shell) && contains_open_splits);
+ new_edges_num++;
+ new_loops_num += 2u - (uint)(!(do_rim && do_shell) && contains_open_splits);
}
new_verts = 0;
contains_open_splits = false;
@@ -1356,7 +1356,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Free vert_adj_edges memory. */
{
uint i = 0;
- for (OldVertEdgeRef **p = vert_adj_edges; i < numVerts; i++, p++) {
+ for (OldVertEdgeRef **p = vert_adj_edges; i < verts_num; i++, p++) {
if (*p) {
MEM_freeN((*p)->edges);
MEM_freeN(*p);
@@ -1375,10 +1375,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
float *face_weight = NULL;
if (do_flat_faces) {
- face_weight = MEM_malloc_arrayN(numPolys, sizeof(*face_weight), "face_weight in solidify");
+ face_weight = MEM_malloc_arrayN(polys_num, sizeof(*face_weight), "face_weight in solidify");
mp = orig_mpoly;
- for (uint i = 0; i < numPolys; i++, mp++) {
+ for (uint i = 0; i < polys_num; i++, mp++) {
float scalar_vgroup = 1.0f;
int loopend = mp->loopstart + mp->totloop;
ml = orig_mloop + mp->loopstart;
@@ -1399,7 +1399,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
mv = orig_mvert;
gs_ptr = orig_vert_groups_arr;
- for (uint i = 0; i < numVerts; i++, mv++, gs_ptr++) {
+ for (uint i = 0; i < verts_num; i++, mv++, gs_ptr++) {
if (*gs_ptr) {
EdgeGroup *g = *gs_ptr;
for (uint j = 0; g->valid; j++, g++) {
@@ -1912,7 +1912,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
uint singularity_edges_len = 1;
singularity_edges = MEM_malloc_arrayN(
singularity_edges_len, sizeof(*singularity_edges), "singularity_edges in solidify");
- for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < numEdges; i++, new_edges++) {
+ for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < edges_num; i++, new_edges++) {
if (*new_edges && (do_shell || edge_adj_faces_len[i] == 1) && (**new_edges)->old_edge == i) {
for (NewEdgeRef **l = *new_edges; *l; l++) {
if ((*l)->link_edge_groups[0]->is_singularity &&
@@ -1940,12 +1940,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
singularity_edges[totsingularity][1] = v2;
totsingularity++;
if (edge_adj_faces_len[i] == 1 && do_rim) {
- numNewLoops -= 2;
- numNewPolys--;
+ new_loops_num -= 2;
+ new_polys_num--;
}
}
else {
- numNewEdges--;
+ new_edges_num--;
}
}
}
@@ -1954,8 +1954,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
/* Create Mesh *result with proper capacity. */
- result = BKE_mesh_new_nomain_from_template(
- mesh, (int)(numNewVerts), (int)(numNewEdges), 0, (int)(numNewLoops), (int)(numNewPolys));
+ result = BKE_mesh_new_nomain_from_template(mesh,
+ (int)(new_verts_num),
+ (int)(new_edges_num),
+ 0,
+ (int)(new_loops_num),
+ (int)(new_polys_num));
mpoly = result->mpoly;
mloop = result->mloop;
@@ -1982,10 +1986,22 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
result->dvert = dvert;
}
+ /* Get vertex crease layer and ensure edge creases are active if vertex creases are found, since
+ * they will introduce edge creases in the used custom interpolation method. */
+ const float *vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE);
+ if (vertex_crease) {
+ result->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ /* delete all vertex creases in the result if a rim is used. */
+ if (do_rim) {
+ CustomData_free_layers(&result->vdata, CD_CREASE, result->totvert);
+ result->cd_flag &= (char)(~ME_CDFLAG_VERT_CREASE);
+ }
+ }
+
/* Make_new_verts. */
{
gs_ptr = orig_vert_groups_arr;
- for (uint i = 0; i < numVerts; i++, gs_ptr++) {
+ for (uint i = 0; i < verts_num; i++, gs_ptr++) {
EdgeGroup *gs = *gs_ptr;
if (gs) {
EdgeGroup *g = gs;
@@ -2006,7 +2022,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
{
uint i = 0;
edge_index += totsingularity;
- for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < numEdges; i++, new_edges++) {
+ for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < edges_num; i++, new_edges++) {
if (*new_edges && (do_shell || edge_adj_faces_len[i] == 1) && (**new_edges)->old_edge == i) {
for (NewEdgeRef **l = *new_edges; *l; l++) {
if ((*l)->new_edge != MOD_SOLIDIFY_EMPTY_TAG) {
@@ -2077,7 +2093,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
* }
*/
gs_ptr = orig_vert_groups_arr;
- for (uint i = 0; i < numVerts; i++, gs_ptr++) {
+ for (uint i = 0; i < verts_num; i++, gs_ptr++) {
EdgeGroup *gs = *gs_ptr;
/* check if the vertex is present (may be dissolved because of proximity) */
if (gs) {
@@ -2098,13 +2114,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
{
gs_ptr = orig_vert_groups_arr;
mv = orig_mvert;
- for (uint i = 0; i < numVerts; i++, gs_ptr++, mv++) {
+ for (uint i = 0; i < verts_num; i++, gs_ptr++, mv++) {
EdgeGroup *gs = *gs_ptr;
if (gs) {
EdgeGroup *g = gs;
EdgeGroup *g2 = gs;
EdgeGroup *last_g = NULL;
EdgeGroup *first_g = NULL;
+ char mv_crease = vertex_crease ? (char)(vertex_crease[i] * 255.0f) : 0;
/* Data calculation cache. */
char max_crease;
char last_max_crease = 0;
@@ -2174,7 +2191,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
medge[edge_index].v2 = g->new_vert;
medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER |
((last_flag | flag) & (ME_SEAM | ME_SHARP));
- medge[edge_index].crease = min_cc(last_max_crease, max_crease);
+ medge[edge_index].crease = max_cc(mv_crease, min_cc(last_max_crease, max_crease));
medge[edge_index++].bweight = max_cc(mv->bweight,
min_cc(last_max_bweight, max_bweight));
}
@@ -2202,7 +2219,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
medge[edge_index].v2 = first_g->new_vert;
medge[edge_index].flag = ME_EDGEDRAW | ME_EDGERENDER |
((last_flag | first_flag) & (ME_SEAM | ME_SHARP));
- medge[edge_index].crease = min_cc(last_max_crease, first_max_crease);
+ medge[edge_index].crease = max_cc(mv_crease,
+ min_cc(last_max_crease, first_max_crease));
medge[edge_index++].bweight = max_cc(mv->bweight,
min_cc(last_max_bweight, first_max_bweight));
@@ -2303,7 +2321,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
/* Make boundary faces. */
if (do_rim) {
- for (uint i = 0; i < numEdges; i++) {
+ for (uint i = 0; i < edges_num; i++) {
if (edge_adj_faces_len[i] == 1 && orig_edge_data_arr[i] &&
(*orig_edge_data_arr[i])->old_edge == i) {
NewEdgeRef **new_edges = orig_edge_data_arr[i];
@@ -2459,7 +2477,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
largest_ngon * 2, sizeof(*face_verts), "face_verts in solidify");
uint *face_edges = MEM_malloc_arrayN(
largest_ngon * 2, sizeof(*face_edges), "face_edges in solidify");
- for (uint i = 0; i < numPolys * 2; i++, fr++) {
+ for (uint i = 0; i < polys_num * 2; i++, fr++) {
const uint loopstart = (uint)fr->face->loopstart;
uint totloop = (uint)fr->face->totloop;
uint valid_edges = 0;
@@ -2547,37 +2565,37 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(face_verts);
MEM_freeN(face_edges);
}
- if (edge_index != numNewEdges) {
+ if (edge_index != new_edges_num) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: edges array wrong size: %u instead of %u",
- numNewEdges,
+ new_edges_num,
edge_index);
}
- if (poly_index != numNewPolys) {
+ if (poly_index != new_polys_num) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: polys array wrong size: %u instead of %u",
- numNewPolys,
+ new_polys_num,
poly_index);
}
- if (loop_index != numNewLoops) {
+ if (loop_index != new_loops_num) {
BKE_modifier_set_error(ctx->object,
md,
"Internal Error: loops array wrong size: %u instead of %u",
- numNewLoops,
+ new_loops_num,
loop_index);
}
- BLI_assert(edge_index == numNewEdges);
- BLI_assert(poly_index == numNewPolys);
- BLI_assert(loop_index == numNewLoops);
+ BLI_assert(edge_index == new_edges_num);
+ BLI_assert(poly_index == new_polys_num);
+ BLI_assert(loop_index == new_loops_num);
/* Free remaining memory */
{
MEM_freeN(vm);
MEM_freeN(edge_adj_faces_len);
uint i = 0;
- for (EdgeGroup **p = orig_vert_groups_arr; i < numVerts; i++, p++) {
+ for (EdgeGroup **p = orig_vert_groups_arr; i < verts_num; i++, p++) {
if (*p) {
for (EdgeGroup *eg = *p; eg->valid; eg++) {
MEM_freeN(eg->edges);
@@ -2586,8 +2604,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
}
MEM_freeN(orig_vert_groups_arr);
- i = numEdges;
- for (NewEdgeRef ***p = orig_edge_data_arr + (numEdges - 1); i > 0; i--, p--) {
+ i = edges_num;
+ for (NewEdgeRef ***p = orig_edge_data_arr + (edges_num - 1); i > 0; i--, p--) {
if (*p && (**p)->old_edge == i - 1) {
for (NewEdgeRef **l = *p; *l; l++) {
MEM_freeN(*l);
@@ -2598,7 +2616,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MEM_freeN(orig_edge_data_arr);
MEM_freeN(orig_edge_lengths);
i = 0;
- for (NewFaceRef *p = face_sides_arr; i < numPolys * 2; i++, p++) {
+ for (NewFaceRef *p = face_sides_arr; i < polys_num * 2; i++, p++) {
MEM_freeN(p->link_edges);
}
MEM_freeN(face_sides_arr);
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 973009236ec..249d09e5d2e 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -283,7 +283,7 @@ static void deformMatrices(ModifierData *md,
Mesh *mesh,
float (*vertex_cos)[3],
float (*deform_matrices)[3][3],
- int num_verts)
+ int verts_num)
{
#if !defined(WITH_OPENSUBDIV)
BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv");
@@ -307,7 +307,7 @@ static void deformMatrices(ModifierData *md,
/* Happens on bad topology, but also on empty input mesh. */
return;
}
- BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, num_verts);
+ BKE_subdiv_deform_coarse_vertices(subdiv, mesh, vertex_cos, verts_num);
if (subdiv != runtime_data->subdiv) {
BKE_subdiv_free(subdiv);
}
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index 4ca2e67c334..f3811d98cd1 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -94,7 +94,7 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SurfaceModifierData *surmd = (SurfaceModifierData *)md;
const int cfra = (int)DEG_get_ctime(ctx->depsgraph);
@@ -116,7 +116,7 @@ static void deformVerts(ModifierData *md,
surmd->mesh = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE);
}
else {
- surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, numVerts, false, false);
+ surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false, false);
}
if (!ctx->object->pd) {
@@ -125,7 +125,7 @@ static void deformVerts(ModifierData *md,
}
if (surmd->mesh) {
- uint numverts = 0, i = 0;
+ uint mesh_verts_num = 0, i = 0;
int init = 0;
float *vec;
MVert *x, *v;
@@ -133,9 +133,9 @@ static void deformVerts(ModifierData *md,
BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos);
BKE_mesh_calc_normals(surmd->mesh);
- numverts = surmd->mesh->totvert;
+ mesh_verts_num = surmd->mesh->totvert;
- if (numverts != surmd->numverts || surmd->x == NULL || surmd->v == NULL ||
+ if (mesh_verts_num != surmd->verts_num || surmd->x == NULL || surmd->v == NULL ||
cfra != surmd->cfra + 1) {
if (surmd->x) {
MEM_freeN(surmd->x);
@@ -146,16 +146,16 @@ static void deformVerts(ModifierData *md,
surmd->v = NULL;
}
- surmd->x = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
- surmd->v = MEM_calloc_arrayN(numverts, sizeof(MVert), "MVert");
+ surmd->x = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert");
+ surmd->v = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert");
- surmd->numverts = numverts;
+ surmd->verts_num = mesh_verts_num;
init = 1;
}
/* convert to global coordinates and calculate velocity */
- for (i = 0, x = surmd->x, v = surmd->v; i < numverts; i++, x++, v++) {
+ for (i = 0, x = surmd->x, v = surmd->v; i < mesh_verts_num; i++, x++, v++) {
vec = surmd->mesh->mvert[i].co;
mul_m4_v3(ctx->object->obmat, vec);
@@ -210,7 +210,7 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md)
surmd->bvhtree = NULL;
surmd->x = NULL;
surmd->v = NULL;
- surmd->numverts = 0;
+ surmd->verts_num = 0;
}
ModifierTypeInfo modifierType_Surface = {
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 6926893e188..a80918b8d2b 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -135,7 +135,7 @@ typedef struct SDefBindPoly {
/** Index of the input polygon. */
uint index;
/** Number of vertices in this face. */
- uint numverts;
+ uint verts_num;
/**
* This polygons loop-start.
* \note that we could look this up from the polygon.
@@ -152,8 +152,8 @@ typedef struct SDefBindPoly {
typedef struct SDefBindWeightData {
SDefBindPoly *bind_polys;
- uint numpoly;
- uint numbinds;
+ uint polys_num;
+ uint binds_num;
} SDefBindWeightData;
typedef struct SDefDeformData {
@@ -209,9 +209,9 @@ static void freeData(ModifierData *md)
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
if (smd->verts) {
- for (int i = 0; i < smd->num_bind_verts; i++) {
+ for (int i = 0; i < smd->bind_verts_num; i++) {
if (smd->verts[i].binds) {
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ for (int j = 0; j < smd->verts[i].binds_num; j++) {
MEM_SAFE_FREE(smd->verts[i].binds[j].vert_inds);
MEM_SAFE_FREE(smd->verts[i].binds[j].vert_weights);
}
@@ -234,11 +234,11 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
if (smd->verts) {
tsmd->verts = MEM_dupallocN(smd->verts);
- for (int i = 0; i < smd->num_bind_verts; i++) {
+ for (int i = 0; i < smd->bind_verts_num; i++) {
if (smd->verts[i].binds) {
tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds);
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ for (int j = 0; j < smd->verts[i].binds_num; j++) {
if (smd->verts[i].binds[j].vert_inds) {
tsmd->verts[i].binds[j].vert_inds = MEM_dupallocN(smd->verts[i].binds[j].vert_inds);
}
@@ -283,8 +283,8 @@ static void freeAdjacencyMap(SDefAdjacencyArray *const vert_edges,
static int buildAdjacencyMap(const MPoly *poly,
const MEdge *edge,
const MLoop *const mloop,
- const uint numpoly,
- const uint numedges,
+ const uint polys_num,
+ const uint edges_num,
SDefAdjacencyArray *const vert_edges,
SDefAdjacency *adj,
SDefEdgePolys *const edge_polys)
@@ -292,7 +292,7 @@ static int buildAdjacencyMap(const MPoly *poly,
const MLoop *loop;
/* Find polygons adjacent to edges. */
- for (int i = 0; i < numpoly; i++, poly++) {
+ for (int i = 0; i < polys_num; i++, poly++) {
loop = &mloop[poly->loopstart];
for (int j = 0; j < poly->totloop; j++, loop++) {
@@ -312,7 +312,7 @@ static int buildAdjacencyMap(const MPoly *poly,
}
/* Find edges adjacent to vertices */
- for (int i = 0; i < numedges; i++, edge++) {
+ for (int i = 0; i < edges_num; i++, edge++) {
adj->next = vert_edges[edge->v1].first;
adj->index = i;
vert_edges[edge->v1].first = adj;
@@ -457,7 +457,7 @@ static void freeBindData(SDefBindWeightData *const bwdata)
SDefBindPoly *bpoly = bwdata->bind_polys;
if (bwdata->bind_polys) {
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ for (int i = 0; i < bwdata->polys_num; bpoly++, i++) {
MEM_SAFE_FREE(bpoly->coords);
MEM_SAFE_FREE(bpoly->coords_v2);
}
@@ -498,9 +498,9 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
return NULL;
}
- bwdata->numpoly = data->vert_edges[nearest].num / 2;
+ bwdata->polys_num = data->vert_edges[nearest].num / 2;
- bpoly = MEM_calloc_arrayN(bwdata->numpoly, sizeof(*bpoly), "SDefBindPoly");
+ bpoly = MEM_calloc_arrayN(bwdata->polys_num, sizeof(*bpoly), "SDefBindPoly");
if (bpoly == NULL) {
freeBindData(bwdata);
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
@@ -518,7 +518,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
{
bpoly = bwdata->bind_polys;
- for (int j = 0; j < bwdata->numpoly; bpoly++, j++) {
+ for (int j = 0; j < bwdata->polys_num; bpoly++, j++) {
/* If coords isn't allocated, we have reached the first uninitialized `bpoly`. */
if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) {
break;
@@ -541,7 +541,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
poly = &data->mpoly[bpoly->index];
loop = &data->mloop[poly->loopstart];
- bpoly->numverts = poly->totloop;
+ bpoly->verts_num = poly->totloop;
bpoly->loopstart = poly->loopstart;
bpoly->coords = MEM_malloc_arrayN(
@@ -719,7 +719,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
}
}
- avg_point_dist /= bwdata->numpoly;
+ avg_point_dist /= bwdata->polys_num;
/* If weights 1 and 2 are not infinite, loop over all adjacent edges again,
* and build adjacency dependent angle data (depends on all polygons having been computed) */
@@ -736,7 +736,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
/* Find bind polys corresponding to the edge's adjacent polys */
bpoly = bwdata->bind_polys;
- for (int i = 0, j = 0; (i < bwdata->numpoly) && (j < epolys->num); bpoly++, i++) {
+ for (int i = 0, j = 0; (i < bwdata->polys_num) && (j < epolys->num); bpoly++, i++) {
if (ELEM(bpoly->index, epolys->polys[0], epolys->polys[1])) {
bpolys[j] = bpoly;
@@ -776,7 +776,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
if (!inf_weight_flags) {
bpoly = bwdata->bind_polys;
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ for (int i = 0; i < bwdata->polys_num; bpoly++, i++) {
float corner_angle_weights[2];
float scale_weight, sqr, inv_sqr;
@@ -856,7 +856,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
else if (!(inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST)) {
bpoly = bwdata->bind_polys;
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ for (int i = 0; i < bwdata->polys_num; bpoly++, i++) {
/* Scale the point distance weight by average point distance, and introduce falloff */
bpoly->weight_dist /= avg_point_dist;
bpoly->weight_dist = powf(bpoly->weight_dist, data->falloff);
@@ -871,7 +871,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
/* Final loop, to compute actual weights */
bpoly = bwdata->bind_polys;
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ for (int i = 0; i < bwdata->polys_num; bpoly++, i++) {
/* Weight computation from components */
if (inf_weight_flags & MOD_SDEF_INFINITE_WEIGHT_DIST) {
bpoly->weight = bpoly->weight_dist < FLT_EPSILON ? 1.0f : 0.0f;
@@ -898,7 +898,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
bpoly = bwdata->bind_polys;
- for (int i = 0; i < bwdata->numpoly; bpoly++, i++) {
+ for (int i = 0; i < bwdata->polys_num; bpoly++, i++) {
bpoly->weight /= tot_weight;
/* Evaluate if this poly is relevant to bind */
@@ -907,15 +907,15 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
* should be negligible... */
if (bpoly->weight >= FLT_EPSILON) {
if (bpoly->inside) {
- bwdata->numbinds += 1;
+ bwdata->binds_num += 1;
}
else {
if (bpoly->dominant_angle_weight < FLT_EPSILON ||
1.0f - bpoly->dominant_angle_weight < FLT_EPSILON) {
- bwdata->numbinds += 1;
+ bwdata->binds_num += 1;
}
else {
- bwdata->numbinds += 2;
+ bwdata->binds_num += 2;
}
}
}
@@ -958,7 +958,7 @@ static void bindVert(void *__restrict userdata,
if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) {
sdvert->binds = NULL;
- sdvert->numbinds = 0;
+ sdvert->binds_num = 0;
return;
}
@@ -975,7 +975,7 @@ static void bindVert(void *__restrict userdata,
if (weight <= 0) {
sdvert->binds = NULL;
- sdvert->numbinds = 0;
+ sdvert->binds_num = 0;
return;
}
}
@@ -985,53 +985,53 @@ static void bindVert(void *__restrict userdata,
if (bwdata == NULL) {
sdvert->binds = NULL;
- sdvert->numbinds = 0;
+ sdvert->binds_num = 0;
return;
}
- sdvert->binds = MEM_calloc_arrayN(bwdata->numbinds, sizeof(*sdvert->binds), "SDefVertBindData");
+ sdvert->binds = MEM_calloc_arrayN(bwdata->binds_num, sizeof(*sdvert->binds), "SDefVertBindData");
if (sdvert->binds == NULL) {
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
- sdvert->numbinds = 0;
+ sdvert->binds_num = 0;
return;
}
- sdvert->numbinds = bwdata->numbinds;
+ sdvert->binds_num = bwdata->binds_num;
sdbind = sdvert->binds;
bpoly = bwdata->bind_polys;
- for (int i = 0; i < bwdata->numbinds; bpoly++) {
+ for (int i = 0; i < bwdata->binds_num; bpoly++) {
if (bpoly->weight >= FLT_EPSILON) {
if (bpoly->inside) {
const MLoop *loop = &data->mloop[bpoly->loopstart];
sdbind->influence = bpoly->weight;
- sdbind->numverts = bpoly->numverts;
+ sdbind->verts_num = bpoly->verts_num;
sdbind->mode = MOD_SDEF_MODE_NGON;
sdbind->vert_weights = MEM_malloc_arrayN(
- bpoly->numverts, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights");
+ bpoly->verts_num, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights");
if (sdbind->vert_weights == NULL) {
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
return;
}
sdbind->vert_inds = MEM_malloc_arrayN(
- bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefNgonVertInds");
+ bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefNgonVertInds");
if (sdbind->vert_inds == NULL) {
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
return;
}
interp_weights_poly_v2(
- sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2);
+ sdbind->vert_weights, bpoly->coords_v2, bpoly->verts_num, bpoly->point_v2);
/* Re-project vert based on weights and original poly verts,
* to reintroduce poly non-planarity */
zero_v3(point_co_proj);
- for (int j = 0; j < bpoly->numverts; j++, loop++) {
+ for (int j = 0; j < bpoly->verts_num; j++, loop++) {
madd_v3_v3fl(point_co_proj, bpoly->coords[j], sdbind->vert_weights[j]);
sdbind->vert_inds[j] = loop->v;
}
@@ -1048,7 +1048,7 @@ static void bindVert(void *__restrict userdata,
if (1.0f - bpoly->dominant_angle_weight >= FLT_EPSILON) {
sdbind->influence = bpoly->weight * (1.0f - bpoly->dominant_angle_weight);
- sdbind->numverts = bpoly->numverts;
+ sdbind->verts_num = bpoly->verts_num;
sdbind->mode = MOD_SDEF_MODE_CENTROID;
sdbind->vert_weights = MEM_malloc_arrayN(
@@ -1059,7 +1059,7 @@ static void bindVert(void *__restrict userdata,
}
sdbind->vert_inds = MEM_malloc_arrayN(
- bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefCentVertInds");
+ bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefCentVertInds");
if (sdbind->vert_inds == NULL) {
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
return;
@@ -1068,7 +1068,7 @@ static void bindVert(void *__restrict userdata,
sortPolyVertsEdge(sdbind->vert_inds,
&data->mloop[bpoly->loopstart],
bpoly->edge_inds[bpoly->dominant_edge],
- bpoly->numverts);
+ bpoly->verts_num);
copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
@@ -1095,7 +1095,7 @@ static void bindVert(void *__restrict userdata,
if (bpoly->dominant_angle_weight >= FLT_EPSILON) {
sdbind->influence = bpoly->weight * bpoly->dominant_angle_weight;
- sdbind->numverts = bpoly->numverts;
+ sdbind->verts_num = bpoly->verts_num;
sdbind->mode = MOD_SDEF_MODE_LOOPTRI;
sdbind->vert_weights = MEM_malloc_arrayN(
@@ -1106,7 +1106,7 @@ static void bindVert(void *__restrict userdata,
}
sdbind->vert_inds = MEM_malloc_arrayN(
- bpoly->numverts, sizeof(*sdbind->vert_inds), "SDefTriVertInds");
+ bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefTriVertInds");
if (sdbind->vert_inds == NULL) {
data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
return;
@@ -1115,7 +1115,7 @@ static void bindVert(void *__restrict userdata,
sortPolyVertsTri(sdbind->vert_inds,
&data->mloop[bpoly->loopstart],
bpoly->edge_vert_inds[0],
- bpoly->numverts);
+ bpoly->verts_num);
copy_v3_v3(v1, data->targetCos[sdbind->vert_inds[0]]);
copy_v3_v3(v2, data->targetCos[sdbind->vert_inds[1]]);
@@ -1149,25 +1149,25 @@ static void bindVert(void *__restrict userdata,
/* Remove vertices without bind data from the bind array. */
static void compactSparseBinds(SurfaceDeformModifierData *smd)
{
- smd->num_bind_verts = 0;
+ smd->bind_verts_num = 0;
- for (uint i = 0; i < smd->num_mesh_verts; i++) {
- if (smd->verts[i].numbinds > 0) {
- smd->verts[smd->num_bind_verts++] = smd->verts[i];
+ for (uint i = 0; i < smd->mesh_verts_num; i++) {
+ if (smd->verts[i].binds_num > 0) {
+ smd->verts[smd->bind_verts_num++] = smd->verts[i];
}
}
smd->verts = MEM_reallocN_id(
- smd->verts, sizeof(*smd->verts) * smd->num_bind_verts, "SDefBindVerts (sparse)");
+ smd->verts, sizeof(*smd->verts) * smd->bind_verts_num, "SDefBindVerts (sparse)");
}
static bool surfacedeformBind(Object *ob,
SurfaceDeformModifierData *smd_orig,
SurfaceDeformModifierData *smd_eval,
float (*vertexCos)[3],
- uint numverts,
- uint tnumpoly,
- uint tnumverts,
+ uint verts_num,
+ uint tpolys_num,
+ uint tverts_num,
Mesh *target,
Mesh *mesh)
{
@@ -1176,26 +1176,26 @@ static bool surfacedeformBind(Object *ob,
const MPoly *mpoly = target->mpoly;
const MEdge *medge = target->medge;
const MLoop *mloop = target->mloop;
- uint tnumedges = target->totedge;
+ uint tedges_num = target->totedge;
int adj_result;
SDefAdjacencyArray *vert_edges;
SDefAdjacency *adj_array;
SDefEdgePolys *edge_polys;
- vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap");
+ vert_edges = MEM_calloc_arrayN(tverts_num, sizeof(*vert_edges), "SDefVertEdgeMap");
if (vert_edges == NULL) {
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
return false;
}
- adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge");
+ adj_array = MEM_malloc_arrayN(tedges_num, 2 * sizeof(*adj_array), "SDefVertEdge");
if (adj_array == NULL) {
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
MEM_freeN(vert_edges);
return false;
}
- edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap");
+ edge_polys = MEM_calloc_arrayN(tedges_num, sizeof(*edge_polys), "SDefEdgeFaceMap");
if (edge_polys == NULL) {
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
MEM_freeN(vert_edges);
@@ -1203,7 +1203,7 @@ static bool surfacedeformBind(Object *ob,
return false;
}
- smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts");
+ smd_orig->verts = MEM_malloc_arrayN(verts_num, sizeof(*smd_orig->verts), "SDefBindVerts");
if (smd_orig->verts == NULL) {
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory");
freeAdjacencyMap(vert_edges, adj_array, edge_polys);
@@ -1220,7 +1220,7 @@ static bool surfacedeformBind(Object *ob,
}
adj_result = buildAdjacencyMap(
- mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys);
+ mpoly, medge, mloop, tpolys_num, tedges_num, vert_edges, adj_array, edge_polys);
if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) {
BKE_modifier_set_error(
@@ -1232,8 +1232,8 @@ static bool surfacedeformBind(Object *ob,
return false;
}
- smd_orig->num_mesh_verts = numverts;
- smd_orig->numpoly = tnumpoly;
+ smd_orig->mesh_verts_num = verts_num;
+ smd_orig->polys_num = tpolys_num;
int defgrp_index;
MDeformVert *dvert;
@@ -1249,7 +1249,7 @@ static bool surfacedeformBind(Object *ob,
.medge = medge,
.mloop = mloop,
.looptri = BKE_mesh_runtime_looptri_ensure(target),
- .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetBindVertArray"),
+ .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetBindVertArray"),
.bind_verts = smd_orig->verts,
.vertexCos = vertexCos,
.falloff = smd_orig->falloff,
@@ -1268,14 +1268,14 @@ static bool surfacedeformBind(Object *ob,
invert_m4_m4(data.imat, smd_orig->mat);
- for (int i = 0; i < tnumverts; i++) {
+ for (int i = 0; i < tverts_num; i++) {
mul_v3_m4v3(data.targetCos[i], smd_orig->mat, mvert[i].co);
}
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numverts > 10000);
- BLI_task_parallel_range(0, numverts, &data, bindVert, &settings);
+ settings.use_threading = (verts_num > 10000);
+ BLI_task_parallel_range(0, verts_num, &data, bindVert, &settings);
MEM_freeN(data.targetCos);
@@ -1283,7 +1283,7 @@ static bool surfacedeformBind(Object *ob,
compactSparseBinds(smd_orig);
}
else {
- smd_orig->num_bind_verts = numverts;
+ smd_orig->bind_verts_num = verts_num;
}
if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) {
@@ -1311,7 +1311,7 @@ static bool surfacedeformBind(Object *ob,
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons");
freeData((ModifierData *)smd_orig);
}
- else if (smd_orig->num_bind_verts == 0 || !smd_orig->verts) {
+ else if (smd_orig->bind_verts_num == 0 || !smd_orig->verts) {
data.success = MOD_SDEF_BIND_RESULT_GENERIC_ERR;
BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "No vertices were bound");
freeData((ModifierData *)smd_orig);
@@ -1329,7 +1329,7 @@ static void deformVert(void *__restrict userdata,
{
const SDefDeformData *const data = (SDefDeformData *)userdata;
const SDefBind *sdbind = data->bind_verts[index].binds;
- const int num_binds = data->bind_verts[index].numbinds;
+ const int sdbind_num = data->bind_verts[index].binds_num;
const unsigned int vertex_idx = data->bind_verts[index].vertex_idx;
float *const vertexCos = data->vertexCos[vertex_idx];
float norm[3], temp[3], offset[3];
@@ -1355,8 +1355,8 @@ static void deformVert(void *__restrict userdata,
/* Allocate a `coords_buffer` that fits all the temp-data. */
int max_verts = 0;
- for (int j = 0; j < num_binds; j++) {
- max_verts = MAX2(max_verts, sdbind[j].numverts);
+ for (int j = 0; j < sdbind_num; j++) {
+ max_verts = MAX2(max_verts, sdbind[j].verts_num);
}
const bool big_buffer = max_verts > 256;
@@ -1369,12 +1369,12 @@ static void deformVert(void *__restrict userdata,
coords_buffer = BLI_array_alloca(coords_buffer, max_verts);
}
- for (int j = 0; j < num_binds; j++, sdbind++) {
- for (int k = 0; k < sdbind->numverts; k++) {
+ for (int j = 0; j < sdbind_num; j++, sdbind++) {
+ for (int k = 0; k < sdbind->verts_num; k++) {
copy_v3_v3(coords_buffer[k], data->targetCos[sdbind->vert_inds[k]]);
}
- normal_poly_v3(norm, coords_buffer, sdbind->numverts);
+ normal_poly_v3(norm, coords_buffer, sdbind->verts_num);
zero_v3(temp);
switch (sdbind->mode) {
@@ -1388,7 +1388,7 @@ static void deformVert(void *__restrict userdata,
/* ---------- ngon mode ---------- */
case MOD_SDEF_MODE_NGON: {
- for (int k = 0; k < sdbind->numverts; k++) {
+ for (int k = 0; k < sdbind->verts_num; k++) {
madd_v3_v3fl(temp, coords_buffer[k], sdbind->vert_weights[k]);
}
break;
@@ -1397,7 +1397,7 @@ static void deformVert(void *__restrict userdata,
/* ---------- centroid mode ---------- */
case MOD_SDEF_MODE_CENTROID: {
float cent[3];
- mid_v3_v3_array(cent, coords_buffer, sdbind->numverts);
+ mid_v3_v3_array(cent, coords_buffer, sdbind->verts_num);
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]);
madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]);
@@ -1425,13 +1425,13 @@ static void deformVert(void *__restrict userdata,
static void surfacedeformModifier_do(ModifierData *md,
const ModifierEvalContext *ctx,
float (*vertexCos)[3],
- uint numverts,
+ uint verts_num,
Object *ob,
Mesh *mesh)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *target;
- uint tnumverts, tnumpoly;
+ uint tverts_num, tpolys_num;
/* Exit function if bind flag is not set (free bind data if any). */
if (!(smd->flags & MOD_SDEF_BIND)) {
@@ -1453,8 +1453,8 @@ static void surfacedeformModifier_do(ModifierData *md,
return;
}
- tnumverts = BKE_mesh_wrapper_vert_len(target);
- tnumpoly = BKE_mesh_wrapper_poly_len(target);
+ tverts_num = BKE_mesh_wrapper_vert_len(target);
+ tpolys_num = BKE_mesh_wrapper_poly_len(target);
/* If not bound, execute bind. */
if (smd->verts == NULL) {
@@ -1474,7 +1474,7 @@ static void surfacedeformModifier_do(ModifierData *md,
BKE_mesh_wrapper_ensure_mdata(target);
if (!surfacedeformBind(
- ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target, mesh)) {
+ ob, smd_orig, smd, vertexCos, verts_num, tpolys_num, tverts_num, target, mesh)) {
smd->flags &= ~MOD_SDEF_BIND;
}
/* Early abort, this is binding 'call', no need to perform whole evaluation. */
@@ -1482,14 +1482,14 @@ static void surfacedeformModifier_do(ModifierData *md,
}
/* Poly count checks */
- if (smd->num_mesh_verts != numverts) {
+ if (smd->mesh_verts_num != verts_num) {
BKE_modifier_set_error(
- ob, md, "Vertices changed from %u to %u", smd->num_mesh_verts, numverts);
+ ob, md, "Vertices changed from %u to %u", smd->mesh_verts_num, verts_num);
return;
}
- if (smd->numpoly != tnumpoly) {
+ if (smd->polys_num != tpolys_num) {
BKE_modifier_set_error(
- ob, md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
+ ob, md, "Target polygons changed from %u to %u", smd->polys_num, tpolys_num);
return;
}
@@ -1507,7 +1507,7 @@ static void surfacedeformModifier_do(ModifierData *md,
/* Actual vertex location update starts here */
SDefDeformData data = {
.bind_verts = smd->verts,
- .targetCos = MEM_malloc_arrayN(tnumverts, sizeof(float[3]), "SDefTargetVertArray"),
+ .targetCos = MEM_malloc_arrayN(tverts_num, sizeof(float[3]), "SDefTargetVertArray"),
.vertexCos = vertexCos,
.dvert = dvert,
.defgrp_index = defgrp_index,
@@ -1516,12 +1516,12 @@ static void surfacedeformModifier_do(ModifierData *md,
};
if (data.targetCos != NULL) {
- BKE_mesh_wrapper_vert_coords_copy_with_mat4(target, data.targetCos, tnumverts, smd->mat);
+ BKE_mesh_wrapper_vert_coords_copy_with_mat4(target, data.targetCos, tverts_num, smd->mat);
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (smd->num_bind_verts > 10000);
- BLI_task_parallel_range(0, smd->num_bind_verts, &data, deformVert, &settings);
+ settings.use_threading = (smd->bind_verts_num > 10000);
+ BLI_task_parallel_range(0, smd->bind_verts_num, &data, deformVert, &settings);
MEM_freeN(data.targetCos);
}
@@ -1531,17 +1531,17 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *mesh_src = NULL;
if (smd->defgrp_name[0] != '\0') {
/* Only need to use mesh_src when a vgroup is used. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+ surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -1553,17 +1553,17 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
Mesh *mesh_src = NULL;
if (smd->defgrp_name[0] != '\0') {
/* Only need to use mesh_src when a vgroup is used. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false, false);
}
- surfacedeformModifier_do(md, ctx, vertexCos, numVerts, ctx->object, mesh_src);
+ surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -1633,23 +1633,23 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md)
{
const SurfaceDeformModifierData *smd = (const SurfaceDeformModifierData *)md;
- BLO_write_struct_array(writer, SDefVert, smd->num_bind_verts, smd->verts);
+ BLO_write_struct_array(writer, SDefVert, smd->bind_verts_num, smd->verts);
if (smd->verts) {
- for (int i = 0; i < smd->num_bind_verts; i++) {
- BLO_write_struct_array(writer, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds);
+ for (int i = 0; i < smd->bind_verts_num; i++) {
+ BLO_write_struct_array(writer, SDefBind, smd->verts[i].binds_num, smd->verts[i].binds);
if (smd->verts[i].binds) {
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ for (int j = 0; j < smd->verts[i].binds_num; j++) {
BLO_write_uint32_array(
- writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds);
+ writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_inds);
if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) {
BLO_write_float3_array(writer, 1, smd->verts[i].binds[j].vert_weights);
}
else {
BLO_write_float_array(
- writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_weights);
+ writer, smd->verts[i].binds[j].verts_num, smd->verts[i].binds[j].vert_weights);
}
}
}
@@ -1664,20 +1664,20 @@ static void blendRead(BlendDataReader *reader, ModifierData *md)
BLO_read_data_address(reader, &smd->verts);
if (smd->verts) {
- for (int i = 0; i < smd->num_bind_verts; i++) {
+ for (int i = 0; i < smd->bind_verts_num; i++) {
BLO_read_data_address(reader, &smd->verts[i].binds);
if (smd->verts[i].binds) {
- for (int j = 0; j < smd->verts[i].numbinds; j++) {
+ for (int j = 0; j < smd->verts[i].binds_num; j++) {
BLO_read_uint32_array(
- reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_inds);
+ reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_inds);
if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) {
BLO_read_float3_array(reader, 1, &smd->verts[i].binds[j].vert_weights);
}
else {
BLO_read_float_array(
- reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_weights);
+ reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_weights);
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index e560a859735..d7e57c1f6e5 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -43,7 +43,7 @@ static Mesh *triangulate_mesh(Mesh *mesh,
{
Mesh *result;
BMesh *bm;
- int total_edges, i;
+ int edges_num, i;
MEdge *me;
CustomData_MeshMasks cd_mask_extra = {
.vmask = CD_MASK_ORIGINDEX, .emask = CD_MASK_ORIGINDEX, .pmask = CD_MASK_ORIGINDEX};
@@ -81,11 +81,11 @@ static Mesh *triangulate_mesh(Mesh *mesh,
CustomData_set_layer_flag(&result->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
}
- total_edges = result->totedge;
+ edges_num = result->totedge;
me = result->medge;
/* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */
- for (i = 0; i < total_edges; i++, me++) {
+ for (i = 0; i < edges_num; i++, me++) {
me->flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index a8c52108cc0..a58e8e23147 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -63,7 +63,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
float (*cos)[3],
float (*r_texco)[3])
{
- const int numVerts = mesh->totvert;
+ const int verts_num = mesh->totvert;
int i;
int texmapping = dmd->texmapping;
float mapref_imat[4][4];
@@ -97,8 +97,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
MPoly *mpoly = mesh->mpoly;
MPoly *mp;
MLoop *mloop = mesh->mloop;
- BLI_bitmap *done = BLI_BITMAP_NEW(numVerts, __func__);
- const int numPolys = mesh->totpoly;
+ BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__);
+ const int polys_num = mesh->totpoly;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
MLoopUV *mloop_uv;
@@ -106,7 +106,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
mloop_uv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
/* verts are given the UV from the first face that uses them */
- for (i = 0, mp = mpoly; i < numPolys; i++, mp++) {
+ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
uint fidx = mp->totloop - 1;
do {
@@ -132,7 +132,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
}
MVert *mv = mesh->mvert;
- for (i = 0; i < numVerts; i++, mv++, r_texco++) {
+ for (i = 0; i < verts_num; i++, mv++, r_texco++) {
switch (texmapping) {
case MOD_DISP_MAP_LOCAL:
copy_v3_v3(*r_texco, cos != NULL ? *cos : mv->co);
@@ -169,7 +169,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
struct BMEditMesh *em,
Mesh *mesh,
const float (*vertexCos)[3],
- const int num_verts,
+ const int verts_num,
const bool use_normals,
const bool use_orco)
{
@@ -212,7 +212,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
/* Currently, that may not be the case every time
* (texts e.g. tend to give issues,
* also when deforming curve points instead of generated curve geometry... ). */
- if (mesh != NULL && mesh->totvert != num_verts) {
+ if (mesh != NULL && mesh->totvert != verts_num) {
BKE_id_free(NULL, mesh);
mesh = NULL;
}
@@ -227,7 +227,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
}
if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) {
- BLI_assert(mesh->totvert == num_verts);
+ BLI_assert(mesh->totvert == verts_num);
}
return mesh;
diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h
index 4578d2c4862..aef254b1103 100644
--- a/source/blender/modifiers/intern/MOD_util.h
+++ b/source/blender/modifiers/intern/MOD_util.h
@@ -37,7 +37,7 @@ struct Mesh *MOD_deform_mesh_eval_get(struct Object *ob,
struct BMEditMesh *em,
struct Mesh *mesh,
const float (*vertexCos)[3],
- int num_verts,
+ int verts_num,
bool use_normals,
bool use_orco);
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 642aac17efd..d4d7ecef283 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -72,7 +72,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
{
UVProjectModifierData *umd = (UVProjectModifierData *)md;
bool do_add_own_transform = false;
- for (int i = 0; i < umd->num_projectors; i++) {
+ for (int i = 0; i < umd->projectors_num; i++) {
if (umd->projectors[i] != NULL) {
DEG_add_object_relation(
ctx->node, umd->projectors[i], DEG_OB_COMP_TRANSFORM, "UV Project Modifier");
@@ -98,11 +98,11 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
{
float(*coords)[3], (*co)[3];
MLoopUV *mloop_uv;
- int i, numVerts, numPolys, numLoops;
+ int i, verts_num, polys_num, loops_num;
MPoly *mpoly, *mp;
MLoop *mloop;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
- int num_projectors = 0;
+ int projectors_num = 0;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
float aspx = umd->aspectx ? umd->aspectx : 1.0f;
float aspy = umd->aspecty ? umd->aspecty : 1.0f;
@@ -110,13 +110,13 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
float scay = umd->scaley ? umd->scaley : 1.0f;
int free_uci = 0;
- for (i = 0; i < umd->num_projectors; i++) {
+ for (i = 0; i < umd->projectors_num; i++) {
if (umd->projectors[i] != NULL) {
- projectors[num_projectors++].ob = umd->projectors[i];
+ projectors[projectors_num++].ob = umd->projectors[i];
}
}
- if (num_projectors == 0) {
+ if (projectors_num == 0) {
return mesh;
}
@@ -131,7 +131,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
/* calculate a projection matrix and normal for each projector */
- for (i = 0; i < num_projectors; i++) {
+ for (i = 0; i < projectors_num; i++) {
float tmpmat[4][4];
float offsetmat[4][4];
Camera *cam = NULL;
@@ -184,23 +184,23 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
mul_mat3_m4_v3(projectors[i].ob->obmat, projectors[i].normal);
}
- numPolys = mesh->totpoly;
- numLoops = mesh->totloop;
+ polys_num = mesh->totpoly;
+ loops_num = mesh->totloop;
/* make sure we are not modifying the original UV map */
mloop_uv = CustomData_duplicate_referenced_layer_named(
- &mesh->ldata, CD_MLOOPUV, uvname, numLoops);
+ &mesh->ldata, CD_MLOOPUV, uvname, loops_num);
- coords = BKE_mesh_vert_coords_alloc(mesh, &numVerts);
+ coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
/* Convert coords to world-space. */
- for (i = 0, co = coords; i < numVerts; i++, co++) {
+ for (i = 0, co = coords; i < verts_num; i++, co++) {
mul_m4_v3(ob->obmat, *co);
}
/* if only one projector, project coords to UVs */
- if (num_projectors == 1 && projectors[0].uci == NULL) {
- for (i = 0, co = coords; i < numVerts; i++, co++) {
+ if (projectors_num == 1 && projectors[0].uci == NULL) {
+ for (i = 0, co = coords; i < verts_num; i++, co++) {
mul_project_m4_v3(projectors[0].projmat, *co);
}
}
@@ -209,8 +209,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
mloop = mesh->mloop;
/* apply coords as UVs */
- for (i = 0, mp = mpoly; i < numPolys; i++, mp++) {
- if (num_projectors == 1) {
+ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
+ if (projectors_num == 1) {
if (projectors[0].uci) {
uint fidx = mp->totloop - 1;
do {
@@ -246,7 +246,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
best_dot = dot_v3v3(projectors[0].normal, face_no);
best_projector = &projectors[0];
- for (j = 1; j < num_projectors; j++) {
+ for (j = 1; j < projectors_num; j++) {
float tmp_dot = dot_v3v3(projectors[j].normal, face_no);
if (tmp_dot > best_dot) {
best_dot = tmp_dot;
@@ -277,7 +277,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
if (free_uci) {
int j;
- for (j = 0; j < num_projectors; j++) {
+ for (j = 0; j < projectors_num; j++) {
if (projectors[j].uci) {
MEM_freeN(projectors[j].uci);
}
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index 0574b1897de..a15efdaa381 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -130,7 +130,7 @@ static void uv_warp_compute(void *__restrict userdata,
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
UVWarpModifierData *umd = (UVWarpModifierData *)md;
- int numPolys, numLoops;
+ int polys_num, loops_num;
MPoly *mpoly;
MLoop *mloop;
MLoopUV *mloopuv;
@@ -196,14 +196,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* make sure we're using an existing layer */
CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
- numPolys = mesh->totpoly;
- numLoops = mesh->totloop;
+ polys_num = mesh->totpoly;
+ loops_num = mesh->totloop;
mpoly = mesh->mpoly;
mloop = mesh->mloop;
/* make sure we are not modifying the original UV map */
mloopuv = CustomData_duplicate_referenced_layer_named(
- &mesh->ldata, CD_MLOOPUV, uvname, numLoops);
+ &mesh->ldata, CD_MLOOPUV, uvname, loops_num);
MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
UVWarpData data = {
@@ -217,8 +217,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
};
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numPolys > 1000);
- BLI_task_parallel_range(0, numPolys, &data, uv_warp_compute, &settings);
+ settings.use_threading = (polys_num > 1000);
+ BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings);
mesh->runtime.is_original = false;
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 045b8e16736..8042172f204 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -181,7 +181,7 @@ static void warpModifier_do(WarpModifierData *wmd,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
Object *ob = ctx->object;
float obinv[4][4];
@@ -245,13 +245,13 @@ static void warpModifier_do(WarpModifierData *wmd,
Tex *tex_target = wmd->texture;
if (mesh != NULL && tex_target != NULL) {
- tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "warpModifier_do tex_co");
+ tex_co = MEM_malloc_arrayN(verts_num, sizeof(*tex_co), "warpModifier_do tex_co");
MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
}
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float *co = vertexCos[i];
if (wmd->falloff_type == eWarp_Falloff_None ||
@@ -344,17 +344,17 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
WarpModifierData *wmd = (WarpModifierData *)md;
Mesh *mesh_src = NULL;
if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
/* mesh_src is only needed for vgroups and textures. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
- warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
+ warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -366,14 +366,14 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *em,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
WarpModifierData *wmd = (WarpModifierData *)md;
Mesh *mesh_src = NULL;
if (wmd->defgrp_name[0] != '\0' || wmd->texture != NULL) {
/* mesh_src is only needed for vgroups and textures. */
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false, false);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -381,7 +381,7 @@ static void deformVertsEM(ModifierData *md,
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- warpModifier_do(wmd, ctx, mesh_src, vertexCos, numVerts);
+ warpModifier_do(wmd, ctx, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 9518cc253e7..4da2d67b8a6 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -133,7 +133,7 @@ static void waveModifier_do(WaveModifierData *md,
Object *ob,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
MVert *mvert = NULL;
@@ -188,7 +188,7 @@ static void waveModifier_do(WaveModifierData *md,
Tex *tex_target = wmd->texture;
if (mesh != NULL && tex_target != NULL) {
- tex_co = MEM_malloc_arrayN(numVerts, sizeof(*tex_co), "waveModifier_do tex_co");
+ tex_co = MEM_malloc_arrayN(verts_num, sizeof(*tex_co), "waveModifier_do tex_co");
MOD_get_texture_coords((MappingInfoModifierData *)wmd, ctx, ob, mesh, vertexCos, tex_co);
MOD_init_texture((MappingInfoModifierData *)wmd, ctx);
@@ -199,7 +199,7 @@ static void waveModifier_do(WaveModifierData *md,
float falloff_inv = falloff != 0.0f ? 1.0f / falloff : 1.0f;
int i;
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
float *co = vertexCos[i];
float x = co[0] - wmd->startx;
float y = co[1] - wmd->starty;
@@ -299,19 +299,20 @@ static void deformVerts(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
Mesh *mesh_src = NULL;
if (wmd->flag & MOD_WAVE_NORM) {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, vertexCos, numVerts, true, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, NULL, mesh, vertexCos, verts_num, true, false);
}
else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
}
- waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
@@ -323,17 +324,18 @@ static void deformVertsEM(ModifierData *md,
struct BMEditMesh *editData,
Mesh *mesh,
float (*vertexCos)[3],
- int numVerts)
+ int verts_num)
{
WaveModifierData *wmd = (WaveModifierData *)md;
Mesh *mesh_src = NULL;
if (wmd->flag & MOD_WAVE_NORM) {
mesh_src = MOD_deform_mesh_eval_get(
- ctx->object, editData, mesh, vertexCos, numVerts, true, false);
+ ctx->object, editData, mesh, vertexCos, verts_num, true, false);
}
else if (wmd->texture != NULL || wmd->defgrp_name[0] != '\0') {
- mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, numVerts, false, false);
+ mesh_src = MOD_deform_mesh_eval_get(
+ ctx->object, editData, mesh, NULL, verts_num, false, false);
}
/* TODO(Campbell): use edit-mode data only (remove this line). */
@@ -341,7 +343,7 @@ static void deformVertsEM(ModifierData *md,
BKE_mesh_wrapper_ensure_mdata(mesh_src);
}
- waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, numVerts);
+ waveModifier_do(wmd, ctx, ctx->object, mesh_src, vertexCos, verts_num);
if (!ELEM(mesh_src, NULL, mesh)) {
BKE_id_free(NULL, mesh_src);
diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c
index 873372a35b8..c79dbdb0b1a 100644
--- a/source/blender/modifiers/intern/MOD_weighted_normal.c
+++ b/source/blender/modifiers/intern/MOD_weighted_normal.c
@@ -58,7 +58,7 @@ static int modepair_cmp_by_val_inverse(const void *p1, const void *p2)
typedef struct WeightedNormalDataAggregateItem {
float normal[3];
- int num_loops; /* Count number of loops using this item so far. */
+ int loops_num; /* Count number of loops using this item so far. */
float curr_val; /* Current max val for this item. */
int curr_strength; /* Current max strength encountered for this item. */
} WeightedNormalDataAggregateItem;
@@ -66,10 +66,10 @@ typedef struct WeightedNormalDataAggregateItem {
#define NUM_CACHED_INVERSE_POWERS_OF_WEIGHT 128
typedef struct WeightedNormalData {
- const int numVerts;
- const int numEdges;
- const int numLoops;
- const int numPolys;
+ const int verts_num;
+ const int edges_num;
+ const int loops_num;
+ const int polys_num;
MVert *mvert;
const float (*vert_normals)[3];
@@ -116,7 +116,7 @@ static bool check_item_poly_strength(WeightedNormalData *wn_data,
if (mp_strength > item_data->curr_strength) {
item_data->curr_strength = mp_strength;
item_data->curr_val = 0.0f;
- item_data->num_loops = 0;
+ item_data->loops_num = 0;
zero_v3(item_data->normal);
}
@@ -160,20 +160,20 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd,
}
if (!compare_ff(item_data->curr_val, curr_val, wnmd->thresh)) {
/* item's curr_val and present value differ more than threshold, update. */
- item_data->num_loops++;
+ item_data->loops_num++;
item_data->curr_val = curr_val;
}
/* Exponentially divided weight for each normal
* (since a few values will be used by most cases, we cache those). */
- const int num_loops = item_data->num_loops;
- if (num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT &&
- cached_inverse_powers_of_weight[num_loops] == 0.0f) {
- cached_inverse_powers_of_weight[num_loops] = 1.0f / powf(weight, num_loops);
+ const int loops_num = item_data->loops_num;
+ if (loops_num < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT &&
+ cached_inverse_powers_of_weight[loops_num] == 0.0f) {
+ cached_inverse_powers_of_weight[loops_num] = 1.0f / powf(weight, loops_num);
}
- const float inverted_n_weight = num_loops < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ?
- cached_inverse_powers_of_weight[num_loops] :
- 1.0f / powf(weight, num_loops);
+ const float inverted_n_weight = loops_num < NUM_CACHED_INVERSE_POWERS_OF_WEIGHT ?
+ cached_inverse_powers_of_weight[loops_num] :
+ 1.0f / powf(weight, loops_num);
madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight);
}
@@ -181,10 +181,10 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd,
static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
WeightedNormalData *wn_data)
{
- const int numVerts = wn_data->numVerts;
- const int numEdges = wn_data->numEdges;
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
+ const int verts_num = wn_data->verts_num;
+ const int edges_num = wn_data->edges_num;
+ const int loops_num = wn_data->loops_num;
+ const int polys_num = wn_data->polys_num;
MVert *mvert = wn_data->mvert;
MEdge *medge = wn_data->medge;
@@ -214,39 +214,39 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
float(*loop_normals)[3] = NULL;
WeightedNormalDataAggregateItem *items_data = NULL;
- int num_items = 0;
+ int items_num = 0;
if (keep_sharp) {
- BLI_bitmap *done_loops = BLI_BITMAP_NEW(numLoops, __func__);
+ BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_num, __func__);
/* This will give us loop normal spaces,
* we do not actually care about computed loop_normals for now... */
- loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
+ loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__);
BKE_mesh_normals_loop_split(mvert,
wn_data->vert_normals,
- numVerts,
+ verts_num,
medge,
- numEdges,
+ edges_num,
mloop,
loop_normals,
- numLoops,
+ loops_num,
mpoly,
polynors,
- numPolys,
+ polys_num,
true,
split_angle,
&lnors_spacearr,
has_clnors ? clnors : NULL,
loop_to_poly);
- num_items = lnors_spacearr.num_spaces;
- items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
+ items_num = lnors_spacearr.spaces_num;
+ items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__);
/* In this first loop, we assign each WeightedNormalDataAggregateItem
* to its smooth fan of loops (aka lnor space). */
MPoly *mp;
int mp_index;
int item_index;
- for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < numPolys; mp++, mp_index++) {
+ for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < polys_num; mp++, mp_index++) {
int ml_index = mp->loopstart;
const int ml_end_index = ml_index + mp->totloop;
@@ -255,7 +255,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
/* Smooth fan of this loop has already been processed, skip it. */
continue;
}
- BLI_assert(item_index < num_items);
+ BLI_assert(item_index < items_num);
WeightedNormalDataAggregateItem *itdt = &items_data[item_index];
itdt->curr_strength = FACE_STRENGTH_WEAK;
@@ -280,10 +280,10 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
MEM_freeN(done_loops);
}
else {
- num_items = numVerts;
- items_data = MEM_calloc_arrayN((size_t)num_items, sizeof(*items_data), __func__);
+ items_num = verts_num;
+ items_data = MEM_calloc_arrayN((size_t)items_num, sizeof(*items_data), __func__);
if (use_face_influence) {
- for (int item_index = 0; item_index < num_items; item_index++) {
+ for (int item_index = 0; item_index < items_num; item_index++) {
items_data[item_index].curr_strength = FACE_STRENGTH_WEAK;
}
}
@@ -292,7 +292,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
switch (mode) {
case MOD_WEIGHTEDNORMAL_MODE_FACE:
- for (int i = 0; i < numPolys; i++) {
+ for (int i = 0; i < polys_num; i++) {
const int mp_index = mode_pair[i].index;
const float mp_val = mode_pair[i].val;
@@ -312,7 +312,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
case MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE:
BLI_assert(loop_to_poly != NULL);
- for (int i = 0; i < numLoops; i++) {
+ for (int i = 0; i < loops_num; i++) {
const int ml_index = mode_pair[i].index;
const float ml_val = mode_pair[i].val;
@@ -330,7 +330,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
}
/* Validate computed weighted normals. */
- for (int item_index = 0; item_index < num_items; item_index++) {
+ for (int item_index = 0; item_index < items_num; item_index++) {
if (normalize_v3(items_data[item_index].normal) < CLNORS_VALID_VEC_LEN) {
zero_v3(items_data[item_index].normal);
}
@@ -341,7 +341,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
* Note that loop_normals is already populated with clnors
* (before this modifier is applied, at start of this function),
* so no need to recompute them here. */
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ for (int ml_index = 0; ml_index < loops_num; ml_index++) {
WeightedNormalDataAggregateItem *item_data = lnors_spacearr.lspacearr[ml_index]->user_data;
if (!is_zero_v3(item_data->normal)) {
copy_v3_v3(loop_normals[ml_index], item_data->normal);
@@ -350,15 +350,15 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
BKE_mesh_normals_loop_custom_set(mvert,
wn_data->vert_normals,
- numVerts,
+ verts_num,
medge,
- numEdges,
+ edges_num,
mloop,
loop_normals,
- numLoops,
+ loops_num,
mpoly,
polynors,
- numPolys,
+ polys_num,
clnors);
}
else {
@@ -372,9 +372,9 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
* But think we can live with it for now,
* and it makes code simpler & cleaner. */
float(*vert_normals)[3] = MEM_calloc_arrayN(
- (size_t)numVerts, sizeof(*loop_normals), __func__);
+ (size_t)verts_num, sizeof(*loop_normals), __func__);
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ for (int ml_index = 0; ml_index < loops_num; ml_index++) {
const int mv_index = mloop[ml_index].v;
copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal);
}
@@ -382,39 +382,39 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
BKE_mesh_normals_loop_custom_from_vertices_set(mvert,
wn_data->vert_normals,
vert_normals,
- numVerts,
+ verts_num,
medge,
- numEdges,
+ edges_num,
mloop,
- numLoops,
+ loops_num,
mpoly,
polynors,
- numPolys,
+ polys_num,
clnors);
MEM_freeN(vert_normals);
}
else {
- loop_normals = MEM_calloc_arrayN((size_t)numLoops, sizeof(*loop_normals), __func__);
+ loop_normals = MEM_calloc_arrayN((size_t)loops_num, sizeof(*loop_normals), __func__);
BKE_mesh_normals_loop_split(mvert,
wn_data->vert_normals,
- numVerts,
+ verts_num,
medge,
- numEdges,
+ edges_num,
mloop,
loop_normals,
- numLoops,
+ loops_num,
mpoly,
polynors,
- numPolys,
+ polys_num,
true,
split_angle,
NULL,
has_clnors ? clnors : NULL,
loop_to_poly);
- for (int ml_index = 0; ml_index < numLoops; ml_index++) {
+ for (int ml_index = 0; ml_index < loops_num; ml_index++) {
const int item_index = mloop[ml_index].v;
if (!is_zero_v3(items_data[item_index].normal)) {
copy_v3_v3(loop_normals[ml_index], items_data[item_index].normal);
@@ -423,15 +423,15 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
BKE_mesh_normals_loop_custom_set(mvert,
wn_data->vert_normals,
- numVerts,
+ verts_num,
medge,
- numEdges,
+ edges_num,
mloop,
loop_normals,
- numLoops,
+ loops_num,
mpoly,
polynors,
- numPolys,
+ polys_num,
clnors);
}
}
@@ -444,7 +444,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd,
static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numPolys = wn_data->numPolys;
+ const int polys_num = wn_data->polys_num;
MVert *mvert = wn_data->mvert;
MLoop *mloop = wn_data->mloop;
@@ -453,15 +453,15 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w
MPoly *mp;
int mp_index;
- ModePair *face_area = MEM_malloc_arrayN((size_t)numPolys, sizeof(*face_area), __func__);
+ ModePair *face_area = MEM_malloc_arrayN((size_t)polys_num, sizeof(*face_area), __func__);
ModePair *f_area = face_area;
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++, f_area++) {
+ for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++, f_area++) {
f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert);
f_area->index = mp_index;
}
- qsort(face_area, numPolys, sizeof(*face_area), modepair_cmp_by_val_inverse);
+ qsort(face_area, polys_num, sizeof(*face_area), modepair_cmp_by_val_inverse);
wn_data->mode_pair = face_area;
apply_weights_vertex_normal(wnmd, wn_data);
@@ -469,8 +469,8 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w
static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
+ const int loops_num = wn_data->loops_num;
+ const int polys_num = wn_data->polys_num;
MVert *mvert = wn_data->mvert;
MLoop *mloop = wn_data->mloop;
@@ -479,11 +479,11 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
MPoly *mp;
int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__);
- ModePair *corner_angle = MEM_malloc_arrayN((size_t)numLoops, sizeof(*corner_angle), __func__);
+ ModePair *corner_angle = MEM_malloc_arrayN((size_t)loops_num, sizeof(*corner_angle), __func__);
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
+ for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) {
MLoop *ml_start = &mloop[mp->loopstart];
float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__);
@@ -501,7 +501,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
MEM_freeN(index_angle);
}
- qsort(corner_angle, numLoops, sizeof(*corner_angle), modepair_cmp_by_val_inverse);
+ qsort(corner_angle, loops_num, sizeof(*corner_angle), modepair_cmp_by_val_inverse);
wn_data->loop_to_poly = loop_to_poly;
wn_data->mode_pair = corner_angle;
@@ -510,8 +510,8 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData
static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalData *wn_data)
{
- const int numLoops = wn_data->numLoops;
- const int numPolys = wn_data->numPolys;
+ const int loops_num = wn_data->loops_num;
+ const int polys_num = wn_data->polys_num;
MVert *mvert = wn_data->mvert;
MLoop *mloop = wn_data->mloop;
@@ -520,11 +520,11 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
MPoly *mp;
int mp_index;
- int *loop_to_poly = MEM_malloc_arrayN((size_t)numLoops, sizeof(*loop_to_poly), __func__);
+ int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__);
- ModePair *combined = MEM_malloc_arrayN((size_t)numLoops, sizeof(*combined), __func__);
+ ModePair *combined = MEM_malloc_arrayN((size_t)loops_num, sizeof(*combined), __func__);
- for (mp_index = 0, mp = mpoly; mp_index < numPolys; mp_index++, mp++) {
+ for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) {
MLoop *ml_start = &mloop[mp->loopstart];
float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert);
@@ -544,7 +544,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD
MEM_freeN(index_angle);
}
- qsort(combined, numLoops, sizeof(*combined), modepair_cmp_by_val_inverse);
+ qsort(combined, loops_num, sizeof(*combined), modepair_cmp_by_val_inverse);
wn_data->loop_to_poly = loop_to_poly;
wn_data->mode_pair = combined;
@@ -575,10 +575,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *result;
result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE);
- const int numVerts = result->totvert;
- const int numEdges = result->totedge;
- const int numLoops = result->totloop;
- const int numPolys = result->totpoly;
+ const int verts_num = result->totvert;
+ const int edges_num = result->totedge;
+ const int loops_num = result->totloop;
+ const int polys_num = result->totpoly;
MEdge *medge = result->medge;
MPoly *mpoly = result->mpoly;
@@ -611,7 +611,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
* it helps when generating clnor spaces and default normals. */
const bool has_clnors = clnors != NULL;
if (!clnors) {
- clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, numLoops);
+ clnors = CustomData_add_layer(ldata, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, loops_num);
}
MDeformVert *dvert;
@@ -619,10 +619,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index);
WeightedNormalData wn_data = {
- .numVerts = numVerts,
- .numEdges = numEdges,
- .numLoops = numLoops,
- .numPolys = numPolys,
+ .verts_num = verts_num,
+ .edges_num = edges_num,
+ .loops_num = loops_num,
+ .polys_num = polys_num,
.mvert = mvert,
.vert_normals = BKE_mesh_vertex_normals_ensure(result),
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index a5c901dbe7a..b251825cd95 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -135,7 +135,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx,
float(*tex_co)[3];
/* See mapping note below... */
MappingInfoModifierData t_map;
- const int numVerts = mesh->totvert;
+ const int verts_num = mesh->totvert;
/* Use new generic get_texture_coords, but do not modify our DNA struct for it...
* XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters?
@@ -148,7 +148,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx,
BLI_strncpy(t_map.uvlayer_name, tex_uvlayer_name, sizeof(t_map.uvlayer_name));
t_map.texmapping = tex_mapping;
- tex_co = MEM_calloc_arrayN(numVerts, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co");
+ tex_co = MEM_calloc_arrayN(verts_num, sizeof(*tex_co), "WeightVG Modifier, TEX mode, tex_co");
MOD_get_texture_coords(&t_map, ctx, ob, mesh, NULL, tex_co);
MOD_init_texture(&t_map, ctx);
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index bce8ce82423..02991558c18 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -176,12 +176,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
#endif
/* Get number of verts. */
- const int numVerts = mesh->totvert;
+ const int verts_num = mesh->totvert;
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
- if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
+ if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@@ -201,11 +201,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (has_mdef) {
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num);
}
else {
/* Add a valid data layer! */
- dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, verts_num);
}
/* Ultimate security check. */
if (!dvert) {
@@ -214,10 +214,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
mesh->dvert = dvert;
/* Get org weights, assuming 0.0 for vertices not in given vgroup. */
- org_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, org_w");
- new_w = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGEdit Modifier, new_w");
- dw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw");
- for (i = 0; i < numVerts; i++) {
+ org_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, org_w");
+ new_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, new_w");
+ dw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGEdit Modifier, dw");
+ for (i = 0; i < verts_num; i++) {
dw[i] = BKE_defvert_find_index(&dvert[i], defgrp_index);
if (dw[i]) {
org_w[i] = new_w[i] = dw[i]->weight;
@@ -237,7 +237,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
rng = BLI_rng_new_srandom(BLI_ghashutil_strhash(ctx->object->id.name + 2));
}
- weightvg_do_map(numVerts, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng);
+ weightvg_do_map(verts_num, new_w, wmd->falloff_type, do_invert_mapping, wmd->cmap_curve, rng);
if (rng) {
BLI_rng_free(rng);
@@ -247,7 +247,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Do masking. */
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
- numVerts,
+ verts_num,
NULL,
org_w,
new_w,
@@ -268,7 +268,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
weightvg_update_vg(dvert,
defgrp_index,
dw,
- numVerts,
+ verts_num,
NULL,
org_w,
do_add,
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 7f9bf9d1e80..52c5e96c68e 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -213,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
float *org_w;
float *new_w;
int *tidx, *indices = NULL;
- int numIdx = 0;
+ int index_num = 0;
int i;
const bool invert_vgroup_mask = (wmd->flag & MOD_WVG_MIX_INVERT_VGROUP_MASK) != 0;
const bool do_normalize = (wmd->flag & MOD_WVG_MIX_WEIGHTS_NORMALIZE) != 0;
@@ -233,12 +233,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
#endif
/* Get number of verts. */
- const int numVerts = mesh->totvert;
+ const int verts_num = mesh->totvert;
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
- if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
+ if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@@ -266,11 +266,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
if (has_mdef) {
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num);
}
else {
/* Add a valid data layer! */
- dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
+ dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, verts_num);
}
/* Ultimate security check. */
if (!dvert) {
@@ -279,107 +279,107 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
mesh->dvert = dvert;
/* Find out which vertices to work on. */
- tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGMix Modifier, tidx");
- tdw1 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
- tdw2 = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
+ tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGMix Modifier, tidx");
+ tdw1 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw1");
+ tdw2 = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, tdw2");
switch (wmd->mix_set) {
case MOD_WVG_SET_A:
/* All vertices in first vgroup. */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
MDeformWeight *dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
if (dw) {
- tdw1[numIdx] = dw;
- tdw2[numIdx] = (defgrp_index_other >= 0) ?
- BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
- NULL;
- tidx[numIdx++] = i;
+ tdw1[index_num] = dw;
+ tdw2[index_num] = (defgrp_index_other >= 0) ?
+ BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
+ NULL;
+ tidx[index_num++] = i;
}
}
break;
case MOD_WVG_SET_B:
/* All vertices in second vgroup. */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
MDeformWeight *dw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
NULL;
if (dw) {
- tdw1[numIdx] = BKE_defvert_find_index(&dvert[i], defgrp_index);
- tdw2[numIdx] = dw;
- tidx[numIdx++] = i;
+ tdw1[index_num] = BKE_defvert_find_index(&dvert[i], defgrp_index);
+ tdw2[index_num] = dw;
+ tidx[index_num++] = i;
}
}
break;
case MOD_WVG_SET_OR:
/* All vertices in one vgroup or the other. */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
MDeformWeight *bdw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
NULL;
if (adw || bdw) {
- tdw1[numIdx] = adw;
- tdw2[numIdx] = bdw;
- tidx[numIdx++] = i;
+ tdw1[index_num] = adw;
+ tdw2[index_num] = bdw;
+ tidx[index_num++] = i;
}
}
break;
case MOD_WVG_SET_AND:
/* All vertices in both vgroups. */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
MDeformWeight *adw = BKE_defvert_find_index(&dvert[i], defgrp_index);
MDeformWeight *bdw = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
NULL;
if (adw && bdw) {
- tdw1[numIdx] = adw;
- tdw2[numIdx] = bdw;
- tidx[numIdx++] = i;
+ tdw1[index_num] = adw;
+ tdw2[index_num] = bdw;
+ tidx[index_num++] = i;
}
}
break;
case MOD_WVG_SET_ALL:
default:
/* Use all vertices. */
- for (i = 0; i < numVerts; i++) {
+ for (i = 0; i < verts_num; i++) {
tdw1[i] = BKE_defvert_find_index(&dvert[i], defgrp_index);
tdw2[i] = (defgrp_index_other >= 0) ?
BKE_defvert_find_index(&dvert[i], defgrp_index_other) :
NULL;
}
- numIdx = -1;
+ index_num = -1;
break;
}
- if (numIdx == 0) {
+ if (index_num == 0) {
/* Use no vertices! Hence, return org data. */
MEM_freeN(tdw1);
MEM_freeN(tdw2);
MEM_freeN(tidx);
return mesh;
}
- if (numIdx != -1) {
- indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGMix Modifier, indices");
- memcpy(indices, tidx, sizeof(int) * numIdx);
- dw1 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
- memcpy(dw1, tdw1, sizeof(MDeformWeight *) * numIdx);
+ if (index_num != -1) {
+ indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGMix Modifier, indices");
+ memcpy(indices, tidx, sizeof(int) * index_num);
+ dw1 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw1");
+ memcpy(dw1, tdw1, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tdw1);
- dw2 = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
- memcpy(dw2, tdw2, sizeof(MDeformWeight *) * numIdx);
+ dw2 = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGMix Modifier, dw2");
+ memcpy(dw2, tdw2, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tdw2);
}
else {
/* Use all vertices. */
- numIdx = numVerts;
+ index_num = verts_num;
/* Just copy MDeformWeight pointers arrays, they will be freed at the end. */
dw1 = tdw1;
dw2 = tdw2;
}
MEM_freeN(tidx);
- org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, org_w");
- new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGMix Modifier, new_w");
+ org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, org_w");
+ new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGMix Modifier, new_w");
/* Mix weights. */
- for (i = 0; i < numIdx; i++) {
+ for (i = 0; i < index_num; i++) {
float weight2;
if (invert_vgroup_a) {
org_w[i] = 1.0f - (dw1[i] ? dw1[i]->weight : wmd->default_weight_a);
@@ -400,7 +400,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Do masking. */
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
- numIdx,
+ index_num,
indices,
org_w,
new_w,
@@ -420,13 +420,22 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Update (add to) vgroup.
* XXX Depending on the MOD_WVG_SET_xxx option chosen, we might have to add vertices to vgroup.
*/
- weightvg_update_vg(
- dvert, defgrp_index, dw1, numIdx, indices, org_w, true, -FLT_MAX, false, 0.0f, do_normalize);
+ weightvg_update_vg(dvert,
+ defgrp_index,
+ dw1,
+ index_num,
+ indices,
+ org_w,
+ true,
+ -FLT_MAX,
+ false,
+ 0.0f,
+ do_normalize);
/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
if (do_prev) {
- DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
+ DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
}
#endif
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 647db5c5aa4..7f11d348eff 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -143,7 +143,7 @@ static void vert2geom_task_cb_ex(void *__restrict userdata,
/**
* Find nearest vertex and/or edge and/or face, for each vertex (adapted from shrinkwrap.c).
*/
-static void get_vert2geom_distance(int numVerts,
+static void get_vert2geom_distance(int verts_num,
float (*v_cos)[3],
float *dist_v,
float *dist_e,
@@ -194,10 +194,10 @@ static void get_vert2geom_distance(int numVerts,
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (numVerts > 10000);
+ settings.use_threading = (verts_num > 10000);
settings.userdata_chunk = &data_chunk;
settings.userdata_chunk_size = sizeof(data_chunk);
- BLI_task_parallel_range(0, numVerts, &data, vert2geom_task_cb_ex, &settings);
+ BLI_task_parallel_range(0, verts_num, &data, vert2geom_task_cb_ex, &settings);
if (dist_v) {
free_bvhtree_from_mesh(&treeData_v);
@@ -215,11 +215,11 @@ static void get_vert2geom_distance(int numVerts,
* Note that it works in final world space (i.e. with constraints etc. applied).
*/
static void get_vert2ob_distance(
- int numVerts, float (*v_cos)[3], float *dist, Object *ob, Object *obr)
+ int verts_num, float (*v_cos)[3], float *dist, Object *ob, Object *obr)
{
/* Vertex and ref object coordinates. */
float v_wco[3];
- uint i = numVerts;
+ uint i = verts_num;
while (i-- > 0) {
/* Get world-coordinates of the vertex (constraints and anim included). */
@@ -435,7 +435,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
float *org_w = NULL;
float *new_w = NULL;
int *tidx, *indices = NULL;
- int numIdx = 0;
+ int index_num = 0;
int i;
const bool invert_vgroup_mask = (wmd->proximity_flags & MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK) !=
0;
@@ -450,12 +450,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
#endif
/* Get number of verts. */
- const int numVerts = mesh->totvert;
+ const int verts_num = mesh->totvert;
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
- if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
+ if ((verts_num == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@@ -477,7 +477,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
return mesh;
}
- dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, numVerts);
+ dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num);
/* Ultimate security check. */
if (!dvert) {
return mesh;
@@ -485,31 +485,31 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
mesh->dvert = dvert;
/* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */
- tidx = MEM_malloc_arrayN(numVerts, sizeof(int), "WeightVGProximity Modifier, tidx");
- tw = MEM_malloc_arrayN(numVerts, sizeof(float), "WeightVGProximity Modifier, tw");
- tdw = MEM_malloc_arrayN(numVerts, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
- for (i = 0; i < numVerts; i++) {
+ tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGProximity Modifier, tidx");
+ tw = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGProximity Modifier, tw");
+ tdw = MEM_malloc_arrayN(verts_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, tdw");
+ for (i = 0; i < verts_num; i++) {
MDeformWeight *_dw = BKE_defvert_find_index(&dvert[i], defgrp_index);
if (_dw) {
- tidx[numIdx] = i;
- tw[numIdx] = _dw->weight;
- tdw[numIdx++] = _dw;
+ tidx[index_num] = i;
+ tw[index_num] = _dw->weight;
+ tdw[index_num++] = _dw;
}
}
/* If no vertices found, return org data! */
- if (numIdx == 0) {
+ if (index_num == 0) {
MEM_freeN(tidx);
MEM_freeN(tw);
MEM_freeN(tdw);
return mesh;
}
- if (numIdx != numVerts) {
- indices = MEM_malloc_arrayN(numIdx, sizeof(int), "WeightVGProximity Modifier, indices");
- memcpy(indices, tidx, sizeof(int) * numIdx);
- org_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, org_w");
- memcpy(org_w, tw, sizeof(float) * numIdx);
- dw = MEM_malloc_arrayN(numIdx, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
- memcpy(dw, tdw, sizeof(MDeformWeight *) * numIdx);
+ if (index_num != verts_num) {
+ indices = MEM_malloc_arrayN(index_num, sizeof(int), "WeightVGProximity Modifier, indices");
+ memcpy(indices, tidx, sizeof(int) * index_num);
+ org_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, org_w");
+ memcpy(org_w, tw, sizeof(float) * index_num);
+ dw = MEM_malloc_arrayN(index_num, sizeof(MDeformWeight *), "WeightVGProximity Modifier, dw");
+ memcpy(dw, tdw, sizeof(MDeformWeight *) * index_num);
MEM_freeN(tw);
MEM_freeN(tdw);
}
@@ -517,14 +517,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
org_w = tw;
dw = tdw;
}
- new_w = MEM_malloc_arrayN(numIdx, sizeof(float), "WeightVGProximity Modifier, new_w");
+ new_w = MEM_malloc_arrayN(index_num, sizeof(float), "WeightVGProximity Modifier, new_w");
MEM_freeN(tidx);
/* Get our vertex coordinates. */
- if (numIdx != numVerts) {
+ if (index_num != verts_num) {
float(*tv_cos)[3] = BKE_mesh_vert_coords_alloc(mesh, NULL);
- v_cos = MEM_malloc_arrayN(numIdx, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
- for (i = 0; i < numIdx; i++) {
+ v_cos = MEM_malloc_arrayN(index_num, sizeof(float[3]), "WeightVGProximity Modifier, v_cos");
+ for (i = 0; i < index_num; i++) {
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
}
MEM_freeN(tv_cos);
@@ -536,7 +536,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Compute wanted distances. */
if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
const float dist = get_ob2ob_distance(ob, obr);
- for (i = 0; i < numIdx; i++) {
+ for (i = 0; i < index_num; i++) {
new_w[i] = dist;
}
}
@@ -556,16 +556,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BKE_mesh_wrapper_ensure_mdata(target_mesh);
SpaceTransform loc2trgt;
- float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_v") :
+ float *dists_v = use_trgt_verts ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_v") :
NULL;
- float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_e") :
+ float *dists_e = use_trgt_edges ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_e") :
NULL;
- float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(numIdx, sizeof(float), "dists_f") :
+ float *dists_f = use_trgt_faces ? MEM_malloc_arrayN(index_num, sizeof(float), "dists_f") :
NULL;
BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
- get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
- for (i = 0; i < numIdx; i++) {
+ get_vert2geom_distance(
+ index_num, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
+ for (i = 0; i < index_num; i++) {
new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
if (dists_e) {
new_w[i] = min_ff(dists_e[i], new_w[i]);
@@ -581,18 +582,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Else, fall back to default obj2vert behavior. */
else {
- get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
+ get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
}
}
else {
- get_vert2ob_distance(numIdx, v_cos, new_w, ob, obr);
+ get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
}
}
/* Map distances to weights. */
do_map(ob,
new_w,
- numIdx,
+ index_num,
wmd->min_dist,
wmd->max_dist,
wmd->falloff_type,
@@ -602,7 +603,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Do masking. */
struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
weightvg_do_mask(ctx,
- numIdx,
+ index_num,
indices,
org_w,
new_w,
@@ -621,12 +622,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Update vgroup. Note we never add nor remove vertices from vgroup here. */
weightvg_update_vg(
- dvert, defgrp_index, dw, numIdx, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
+ dvert, defgrp_index, dw, index_num, indices, org_w, false, 0.0f, false, 0.0f, do_normalize);
/* If weight preview enabled... */
#if 0 /* XXX Currently done in mod stack :/ */
if (do_prev) {
- DM_update_weight_mcol(ob, dm, 0, org_w, numIdx, indices);
+ DM_update_weight_mcol(ob, dm, 0, org_w, index_num, indices);
}
#endif
diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt
index b8bdd9859e0..57f76f20ac6 100644
--- a/source/blender/nodes/composite/CMakeLists.txt
+++ b/source/blender/nodes/composite/CMakeLists.txt
@@ -93,9 +93,9 @@ set(SRC
nodes/node_composite_scene_time.cc
nodes/node_composite_sepcomb_hsva.cc
nodes/node_composite_sepcomb_rgba.cc
+ nodes/node_composite_sepcomb_xyz.cc
nodes/node_composite_sepcomb_ycca.cc
nodes/node_composite_sepcomb_yuva.cc
- nodes/node_composite_sepcomb_xyz.cc
nodes/node_composite_setalpha.cc
nodes/node_composite_split_viewer.cc
nodes/node_composite_stabilize2d.cc
diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
index 162ef07a6dd..67d861aad9f 100644
--- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
+++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc
@@ -323,8 +323,8 @@ bNodeSocket *ntreeCompositCryptomatteAddSocket(bNodeTree *ntree, bNode *node)
BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY);
NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
char sockname[32];
- n->num_inputs++;
- BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->num_inputs - 1);
+ n->inputs_num++;
+ BLI_snprintf(sockname, sizeof(sockname), "Crypto %.2d", n->inputs_num - 1);
bNodeSocket *sock = nodeAddStaticSocket(
ntree, node, SOCK_IN, SOCK_RGBA, PROP_NONE, nullptr, sockname);
return sock;
@@ -334,12 +334,12 @@ int ntreeCompositCryptomatteRemoveSocket(bNodeTree *ntree, bNode *node)
{
BLI_assert(node->type == CMP_NODE_CRYPTOMATTE_LEGACY);
NodeCryptomatte *n = static_cast<NodeCryptomatte *>(node->storage);
- if (n->num_inputs < 2) {
+ if (n->inputs_num < 2) {
return 0;
}
bNodeSocket *sock = static_cast<bNodeSocket *>(node->inputs.last);
nodeRemoveSocket(ntree, node, sock);
- n->num_inputs--;
+ n->inputs_num--;
return 1;
}
diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt
index 5c6c7532a0f..84280c0889a 100644
--- a/source/blender/nodes/geometry/CMakeLists.txt
+++ b/source/blender/nodes/geometry/CMakeLists.txt
@@ -58,9 +58,9 @@ set(SRC
nodes/node_geo_curve_to_points.cc
nodes/node_geo_curve_trim.cc
nodes/node_geo_delete_geometry.cc
- nodes/node_geo_duplicate_elements.cc
nodes/node_geo_distribute_points_on_faces.cc
nodes/node_geo_dual_mesh.cc
+ nodes/node_geo_duplicate_elements.cc
nodes/node_geo_edge_split.cc
nodes/node_geo_extrude_mesh.cc
nodes/node_geo_field_at_index.cc
diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
index 87fc6bcbad4..4792fada98b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
@@ -30,25 +30,25 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
{
plConvexHull hull = plConvexHullCompute((float(*)[3])coords.data(), coords.size());
- const int num_verts = plConvexHullNumVertices(hull);
- const int num_faces = num_verts <= 2 ? 0 : plConvexHullNumFaces(hull);
- const int num_loops = num_verts <= 2 ? 0 : plConvexHullNumLoops(hull);
+ const int verts_num = plConvexHullNumVertices(hull);
+ const int faces_num = verts_num <= 2 ? 0 : plConvexHullNumFaces(hull);
+ const int loops_num = verts_num <= 2 ? 0 : plConvexHullNumLoops(hull);
/* Half as many edges as loops, because the mesh is manifold. */
- const int num_edges = num_verts == 2 ? 1 : num_verts < 2 ? 0 : num_loops / 2;
+ const int edges_num = verts_num == 2 ? 1 : verts_num < 2 ? 0 : loops_num / 2;
/* Create Mesh *result with proper capacity. */
Mesh *result;
if (mesh) {
result = BKE_mesh_new_nomain_from_template(
- mesh, num_verts, num_edges, 0, num_loops, num_faces);
+ mesh, verts_num, edges_num, 0, loops_num, faces_num);
}
else {
- result = BKE_mesh_new_nomain(num_verts, num_edges, 0, num_loops, num_faces);
+ result = BKE_mesh_new_nomain(verts_num, edges_num, 0, loops_num, faces_num);
BKE_id_material_eval_ensure_default_slot(&result->id);
}
/* Copy vertices. */
- for (const int i : IndexRange(num_verts)) {
+ for (const int i : IndexRange(verts_num)) {
float co[3];
int original_index;
plConvexHullGetVertex(hull, i, co, &original_index);
@@ -73,9 +73,9 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
/* NOTE: ConvexHull from Bullet uses a half-edge data structure
* for its mesh. To convert that, each half-edge needs to be converted
* to a loop and edges need to be created from that. */
- Array<MLoop> mloop_src(num_loops);
+ Array<MLoop> mloop_src(loops_num);
uint edge_index = 0;
- for (const int i : IndexRange(num_loops)) {
+ for (const int i : IndexRange(loops_num)) {
int v_from;
int v_to;
plConvexHullGetLoop(hull, i, &v_from, &v_to);
@@ -95,7 +95,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
edge_index++;
}
}
- if (num_edges == 1) {
+ if (edges_num == 1) {
/* In this case there are no loops. */
MEdge &edge = result->medge[0];
edge.v1 = 0;
@@ -103,13 +103,13 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
edge.flag |= ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
edge_index++;
}
- BLI_assert(edge_index == num_edges);
+ BLI_assert(edge_index == edges_num);
/* Copy faces. */
Array<int> loops;
int j = 0;
MLoop *loop = result->mloop;
- for (const int i : IndexRange(num_faces)) {
+ for (const int i : IndexRange(faces_num)) {
const int len = plConvexHullGetFaceSize(hull, i);
BLI_assert(len > 2);
@@ -241,7 +241,7 @@ static void read_curve_positions(const Curves &curves_id,
Vector<float3> *r_coords)
{
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- const int total_size = curves.evaluated_points_size();
+ const int total_size = curves.evaluated_points_num();
r_coords->reserve(r_coords->size() + total_size * transforms.size());
r_coords->as_mutable_span().take_back(total_size).copy_from(curves.evaluated_positions());
for (const float3 &position : curves.evaluated_positions()) {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
index 2c72e5f14f5..bbc8758952d 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc
@@ -55,24 +55,24 @@ class EndpointFieldInput final : public GeometryFieldInput {
const Curves &curves_id = *curve_component.get_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- if (curves.points_size() == 0) {
+ if (curves.points_num() == 0) {
return nullptr;
}
GeometryComponentFieldContext size_context{curve_component, ATTR_DOMAIN_CURVE};
- fn::FieldEvaluator evaluator{size_context, curves.curves_size()};
+ fn::FieldEvaluator evaluator{size_context, curves.curves_num()};
evaluator.add(start_size_);
evaluator.add(end_size_);
evaluator.evaluate();
const VArray<int> &start_size = evaluator.get_evaluated<int>(0);
const VArray<int> &end_size = evaluator.get_evaluated<int>(1);
- Array<bool> selection(curves.points_size(), false);
+ Array<bool> selection(curves.points_num(), false);
MutableSpan<bool> selection_span = selection.as_mutable_span();
devirtualize_varray2(start_size, end_size, [&](const auto &start_size, const auto &end_size) {
threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange curves_range) {
for (const int i : curves_range) {
- const IndexRange range = curves.range_for_curve(i);
+ const IndexRange range = curves.points_for_curve(i);
const int start = std::max(start_size[i], 0);
const int end = std::max(end_size[i], 0);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
index 42c83d7a9e5..f29b193d98b 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc
@@ -45,14 +45,14 @@ static meshintersect::CDT_result<double> do_cdt(const bke::CurvesGeometry &curve
{
meshintersect::CDT_input<double> input;
input.need_ids = false;
- input.vert.reinitialize(curves.evaluated_points_size());
- input.face.reinitialize(curves.curves_size());
+ input.vert.reinitialize(curves.evaluated_points_num());
+ input.face.reinitialize(curves.curves_num());
VArray<bool> cyclic = curves.cyclic();
Span<float3> positions = curves.evaluated_positions();
for (const int i_curve : curves.curves_range()) {
- const IndexRange points = curves.evaluated_range_for_curve(i_curve);
+ const IndexRange points = curves.evaluated_points_for_curve(i_curve);
const int segment_size = bke::curves::curve_segment_size(points.size(), cyclic[i_curve]);
for (const int i : points) {
@@ -118,7 +118,7 @@ static void curve_fill_calculate(GeometrySet &geometry_set, const GeometryNodeCu
const Curves &curves_id = *geometry_set.get_curves_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- if (curves.curves_size() == 0) {
+ if (curves.curves_num() == 0) {
geometry_set.replace_curves(nullptr);
return;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
index 81ca87eec25..95ea978541c 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc
@@ -551,8 +551,8 @@ static std::unique_ptr<CurveEval> fillet_curve(const CurveEval &input_curve,
Span<SplinePtr> input_splines = input_curve.splines();
std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>();
- const int num_splines = input_splines.size();
- output_curve->resize(num_splines);
+ const int splines_num = input_splines.size();
+ output_curve->resize(splines_num);
MutableSpan<SplinePtr> output_splines = output_curve->splines();
Array<int> spline_offsets = input_curve.control_point_offsets();
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
index 775376d473e..dc2b9d40894 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc
@@ -57,7 +57,7 @@ static void select_by_handle_type(const bke::CurvesGeometry &curves,
VArray<int8_t> right = curves.handle_types_right();
for (const int i_curve : curves.curves_range()) {
- const IndexRange points = curves.range_for_curve(i_curve);
+ const IndexRange points = curves.points_for_curve(i_curve);
if (curve_types[i_curve] != CURVE_TYPE_BEZIER) {
r_selection.slice(points).fill(false);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
index cf6837817c2..c3b1a141f4a 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc
@@ -168,12 +168,12 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &out_component,
- const int num_selected_loops,
+ const int selected_loops_num,
const Span<int> selected_poly_indices,
const Mesh &mesh_in)
{
Vector<int64_t> indices;
- indices.reserve(num_selected_loops);
+ indices.reserve(selected_loops_num);
for (const int src_poly_index : selected_poly_indices) {
const MPoly &src_poly = mesh_in.mpoly[src_poly_index];
const int src_loop_start = src_poly.loopstart;
@@ -546,47 +546,47 @@ static void separate_instance_selection(GeometrySet &geometry_set,
static void compute_selected_vertices_from_vertex_selection(const Span<bool> vertex_selection,
const bool invert,
MutableSpan<int> r_vertex_map,
- int *r_num_selected_vertices)
+ int *r_selected_vertices_num)
{
BLI_assert(vertex_selection.size() == r_vertex_map.size());
- int num_selected_vertices = 0;
+ int selected_verts_num = 0;
for (const int i : r_vertex_map.index_range()) {
if (vertex_selection[i] != invert) {
- r_vertex_map[i] = num_selected_vertices;
- num_selected_vertices++;
+ r_vertex_map[i] = selected_verts_num;
+ selected_verts_num++;
}
else {
r_vertex_map[i] = -1;
}
}
- *r_num_selected_vertices = num_selected_vertices;
+ *r_selected_vertices_num = selected_verts_num;
}
static void compute_selected_edges_from_vertex_selection(const Mesh &mesh,
const Span<bool> vertex_selection,
const bool invert,
MutableSpan<int> r_edge_map,
- int *r_num_selected_edges)
+ int *r_selected_edges_num)
{
BLI_assert(mesh.totedge == r_edge_map.size());
- int num_selected_edges = 0;
+ int selected_edges_num = 0;
for (const int i : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[i];
/* Only add the edge if both vertices will be in the new mesh. */
if (vertex_selection[edge.v1] != invert && vertex_selection[edge.v2] != invert) {
- r_edge_map[i] = num_selected_edges;
- num_selected_edges++;
+ r_edge_map[i] = selected_edges_num;
+ selected_edges_num++;
}
else {
r_edge_map[i] = -1;
}
}
- *r_num_selected_edges = num_selected_edges;
+ *r_selected_edges_num = selected_edges_num;
}
static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh,
@@ -594,15 +594,15 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh,
const bool invert,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
BLI_assert(mesh.totvert == vertex_selection.size());
r_selected_poly_indices.reserve(mesh.totpoly);
r_loop_starts.reserve(mesh.totloop);
- int num_selected_loops = 0;
+ int selected_loops_num = 0;
for (const int i : IndexRange(mesh.totpoly)) {
const MPoly &poly_src = mesh.mpoly[i];
@@ -617,13 +617,13 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh,
if (all_verts_in_selection) {
r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(selected_loops_num);
+ selected_loops_num += poly_src.totloop;
}
}
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
+ *r_selected_polys_num = r_selected_poly_indices.size();
+ *r_selected_loops_num = selected_loops_num;
}
/**
@@ -636,25 +636,25 @@ static void compute_selected_vertices_and_edges_from_edge_selection(
const bool invert,
MutableSpan<int> r_vertex_map,
MutableSpan<int> r_edge_map,
- int *r_num_selected_vertices,
- int *r_num_selected_edges)
+ int *r_selected_vertices_num,
+ int *r_selected_edges_num)
{
BLI_assert(mesh.totedge == edge_selection.size());
- int num_selected_edges = 0;
- int num_selected_vertices = 0;
+ int selected_edges_num = 0;
+ int selected_verts_num = 0;
for (const int i : IndexRange(mesh.totedge)) {
const MEdge &edge = mesh.medge[i];
if (edge_selection[i] != invert) {
- r_edge_map[i] = num_selected_edges;
- num_selected_edges++;
+ r_edge_map[i] = selected_edges_num;
+ selected_edges_num++;
if (r_vertex_map[edge.v1] == -1) {
- r_vertex_map[edge.v1] = num_selected_vertices;
- num_selected_vertices++;
+ r_vertex_map[edge.v1] = selected_verts_num;
+ selected_verts_num++;
}
if (r_vertex_map[edge.v2] == -1) {
- r_vertex_map[edge.v2] = num_selected_vertices;
- num_selected_vertices++;
+ r_vertex_map[edge.v2] = selected_verts_num;
+ selected_verts_num++;
}
}
else {
@@ -662,8 +662,8 @@ static void compute_selected_vertices_and_edges_from_edge_selection(
}
}
- *r_num_selected_vertices = num_selected_vertices;
- *r_num_selected_edges = num_selected_edges;
+ *r_selected_vertices_num = selected_verts_num;
+ *r_selected_edges_num = selected_edges_num;
}
/**
@@ -673,22 +673,22 @@ static void compute_selected_edges_from_edge_selection(const Mesh &mesh,
const Span<bool> edge_selection,
const bool invert,
MutableSpan<int> r_edge_map,
- int *r_num_selected_edges)
+ int *r_selected_edges_num)
{
BLI_assert(mesh.totedge == edge_selection.size());
- int num_selected_edges = 0;
+ int selected_edges_num = 0;
for (const int i : IndexRange(mesh.totedge)) {
if (edge_selection[i] != invert) {
- r_edge_map[i] = num_selected_edges;
- num_selected_edges++;
+ r_edge_map[i] = selected_edges_num;
+ selected_edges_num++;
}
else {
r_edge_map[i] = -1;
}
}
- *r_num_selected_edges = num_selected_edges;
+ *r_selected_edges_num = selected_edges_num;
}
/**
@@ -700,13 +700,13 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh,
const bool invert,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
r_selected_poly_indices.reserve(mesh.totpoly);
r_loop_starts.reserve(mesh.totloop);
- int num_selected_loops = 0;
+ int selected_loops_num = 0;
for (const int i : IndexRange(mesh.totpoly)) {
const MPoly &poly_src = mesh.mpoly[i];
@@ -721,13 +721,13 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh,
if (all_edges_in_selection) {
r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(selected_loops_num);
+ selected_loops_num += poly_src.totloop;
}
}
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
+ *r_selected_polys_num = r_selected_poly_indices.size();
+ *r_selected_loops_num = selected_loops_num;
}
/**
@@ -740,21 +740,21 @@ static void compute_selected_mesh_data_from_vertex_selection_edge_face(
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
compute_selected_edges_from_vertex_selection(
- mesh, vertex_selection, invert, r_edge_map, r_num_selected_edges);
+ mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num);
compute_selected_polygons_from_vertex_selection(mesh,
vertex_selection,
invert,
r_selected_poly_indices,
r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
+ r_selected_polys_num,
+ r_selected_loops_num);
}
/**
@@ -768,24 +768,24 @@ static void compute_selected_mesh_data_from_vertex_selection(const Mesh &mesh,
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_vertices,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_vertices_num,
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
compute_selected_vertices_from_vertex_selection(
- vertex_selection, invert, r_vertex_map, r_num_selected_vertices);
+ vertex_selection, invert, r_vertex_map, r_selected_vertices_num);
compute_selected_edges_from_vertex_selection(
- mesh, vertex_selection, invert, r_edge_map, r_num_selected_edges);
+ mesh, vertex_selection, invert, r_edge_map, r_selected_edges_num);
compute_selected_polygons_from_vertex_selection(mesh,
vertex_selection,
invert,
r_selected_poly_indices,
r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
+ r_selected_polys_num,
+ r_selected_loops_num);
}
/**
@@ -799,19 +799,19 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face(
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
compute_selected_edges_from_edge_selection(
- mesh, edge_selection, invert, r_edge_map, r_num_selected_edges);
+ mesh, edge_selection, invert, r_edge_map, r_selected_edges_num);
compute_selected_polygons_from_edge_selection(mesh,
edge_selection,
invert,
r_selected_poly_indices,
r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
+ r_selected_polys_num,
+ r_selected_loops_num);
}
/**
@@ -825,10 +825,10 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh,
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_vertices,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_vertices_num,
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
r_vertex_map.fill(-1);
compute_selected_vertices_and_edges_from_edge_selection(mesh,
@@ -836,15 +836,15 @@ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh,
invert,
r_vertex_map,
r_edge_map,
- r_num_selected_vertices,
- r_num_selected_edges);
+ r_selected_vertices_num,
+ r_selected_edges_num);
compute_selected_polygons_from_edge_selection(mesh,
edge_selection,
invert,
r_selected_poly_indices,
r_loop_starts,
- r_num_selected_polys,
- r_num_selected_loops);
+ r_selected_polys_num,
+ r_selected_loops_num);
}
/**
@@ -855,26 +855,26 @@ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh,
const bool invert,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
BLI_assert(mesh.totpoly == poly_selection.size());
r_selected_poly_indices.reserve(mesh.totpoly);
r_loop_starts.reserve(mesh.totloop);
- int num_selected_loops = 0;
+ int selected_loops_num = 0;
for (const int i : IndexRange(mesh.totpoly)) {
const MPoly &poly_src = mesh.mpoly[i];
/* We keep this one. */
if (poly_selection[i] != invert) {
r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(selected_loops_num);
+ selected_loops_num += poly_src.totloop;
}
}
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
+ *r_selected_polys_num = r_selected_poly_indices.size();
+ *r_selected_loops_num = selected_loops_num;
}
/**
* Checks for every polygon if it is in `poly_selection`. If it is, the edges
@@ -887,9 +887,9 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face(
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
BLI_assert(mesh.totpoly == poly_selection.size());
BLI_assert(mesh.totedge == r_edge_map.size());
@@ -898,30 +898,30 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face(
r_selected_poly_indices.reserve(mesh.totpoly);
r_loop_starts.reserve(mesh.totloop);
- int num_selected_loops = 0;
- int num_selected_edges = 0;
+ int selected_loops_num = 0;
+ int selected_edges_num = 0;
for (const int i : IndexRange(mesh.totpoly)) {
const MPoly &poly_src = mesh.mpoly[i];
/* We keep this one. */
if (poly_selection[i] != invert) {
r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(selected_loops_num);
+ selected_loops_num += poly_src.totloop;
/* Add the vertices and the edges. */
Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop);
for (const MLoop &loop : loops_src) {
/* Check first if it has not yet been added. */
if (r_edge_map[loop.e] == -1) {
- r_edge_map[loop.e] = num_selected_edges;
- num_selected_edges++;
+ r_edge_map[loop.e] = selected_edges_num;
+ selected_edges_num++;
}
}
}
}
- *r_num_selected_edges = num_selected_edges;
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
+ *r_selected_edges_num = selected_edges_num;
+ *r_selected_polys_num = r_selected_poly_indices.size();
+ *r_selected_loops_num = selected_loops_num;
}
/**
@@ -935,10 +935,10 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh,
MutableSpan<int> r_edge_map,
Vector<int> &r_selected_poly_indices,
Vector<int> &r_loop_starts,
- int *r_num_selected_vertices,
- int *r_num_selected_edges,
- int *r_num_selected_polys,
- int *r_num_selected_loops)
+ int *r_selected_vertices_num,
+ int *r_selected_edges_num,
+ int *r_selected_polys_num,
+ int *r_selected_loops_num)
{
BLI_assert(mesh.totpoly == poly_selection.size());
BLI_assert(mesh.totedge == r_edge_map.size());
@@ -948,36 +948,36 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh,
r_selected_poly_indices.reserve(mesh.totpoly);
r_loop_starts.reserve(mesh.totloop);
- int num_selected_loops = 0;
- int num_selected_vertices = 0;
- int num_selected_edges = 0;
+ int selected_loops_num = 0;
+ int selected_verts_num = 0;
+ int selected_edges_num = 0;
for (const int i : IndexRange(mesh.totpoly)) {
const MPoly &poly_src = mesh.mpoly[i];
/* We keep this one. */
if (poly_selection[i] != invert) {
r_selected_poly_indices.append_unchecked(i);
- r_loop_starts.append_unchecked(num_selected_loops);
- num_selected_loops += poly_src.totloop;
+ r_loop_starts.append_unchecked(selected_loops_num);
+ selected_loops_num += poly_src.totloop;
/* Add the vertices and the edges. */
Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop);
for (const MLoop &loop : loops_src) {
/* Check first if it has not yet been added. */
if (r_vertex_map[loop.v] == -1) {
- r_vertex_map[loop.v] = num_selected_vertices;
- num_selected_vertices++;
+ r_vertex_map[loop.v] = selected_verts_num;
+ selected_verts_num++;
}
if (r_edge_map[loop.e] == -1) {
- r_edge_map[loop.e] = num_selected_edges;
- num_selected_edges++;
+ r_edge_map[loop.e] = selected_edges_num;
+ selected_edges_num++;
}
}
}
}
- *r_num_selected_vertices = num_selected_vertices;
- *r_num_selected_edges = num_selected_edges;
- *r_num_selected_polys = r_selected_poly_indices.size();
- *r_num_selected_loops = num_selected_loops;
+ *r_selected_vertices_num = selected_verts_num;
+ *r_selected_edges_num = selected_edges_num;
+ *r_selected_polys_num = r_selected_poly_indices.size();
+ *r_selected_loops_num = selected_loops_num;
}
/**
@@ -993,8 +993,8 @@ static void do_mesh_separation(GeometrySet &geometry_set,
/* Needed in all cases. */
Vector<int> selected_poly_indices;
Vector<int> new_loop_starts;
- int num_selected_polys = 0;
- int num_selected_loops = 0;
+ int selected_polys_num = 0;
+ int selected_loops_num = 0;
const Mesh &mesh_in = *in_component.get_for_read();
Mesh *mesh_out;
@@ -1007,10 +1007,10 @@ static void do_mesh_separation(GeometrySet &geometry_set,
switch (mode) {
case GEO_NODE_DELETE_GEOMETRY_MODE_ALL: {
Array<int> vertex_map(mesh_in.totvert);
- int num_selected_vertices = 0;
+ int selected_verts_num = 0;
Array<int> edge_map(mesh_in.totedge);
- int num_selected_edges = 0;
+ int selected_edges_num = 0;
/* Fill all the maps based on the selection. */
switch (domain) {
@@ -1022,10 +1022,10 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_vertices,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_verts_num,
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_EDGE:
compute_selected_mesh_data_from_edge_selection(mesh_in,
@@ -1035,10 +1035,10 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_vertices,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_verts_num,
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_FACE:
compute_selected_mesh_data_from_poly_selection(mesh_in,
@@ -1048,21 +1048,21 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_vertices,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_verts_num,
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
default:
BLI_assert_unreachable();
break;
}
mesh_out = BKE_mesh_new_nomain_from_template(&mesh_in,
- num_selected_vertices,
- num_selected_edges,
+ selected_verts_num,
+ selected_edges_num,
0,
- num_selected_loops,
- num_selected_polys);
+ selected_loops_num,
+ selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
@@ -1084,14 +1084,14 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_face_corner_attributes(attributes,
in_component,
out_component,
- num_selected_loops,
+ selected_loops_num,
selected_poly_indices,
mesh_in);
break;
}
case GEO_NODE_DELETE_GEOMETRY_MODE_EDGE_FACE: {
Array<int> edge_map(mesh_in.totedge);
- int num_selected_edges = 0;
+ int selected_edges_num = 0;
/* Fill all the maps based on the selection. */
switch (domain) {
@@ -1102,9 +1102,9 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_EDGE:
compute_selected_mesh_data_from_edge_selection_edge_face(mesh_in,
@@ -1113,9 +1113,9 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_FACE:
compute_selected_mesh_data_from_poly_selection_edge_face(mesh_in,
@@ -1124,9 +1124,9 @@ static void do_mesh_separation(GeometrySet &geometry_set,
edge_map,
selected_poly_indices,
new_loop_starts,
- &num_selected_edges,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_edges_num,
+ &selected_polys_num,
+ &selected_loops_num);
break;
default:
BLI_assert_unreachable();
@@ -1134,10 +1134,10 @@ static void do_mesh_separation(GeometrySet &geometry_set,
}
mesh_out = BKE_mesh_new_nomain_from_template(&mesh_in,
mesh_in.totvert,
- num_selected_edges,
+ selected_edges_num,
0,
- num_selected_loops,
- num_selected_polys);
+ selected_loops_num,
+ selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
@@ -1158,7 +1158,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_face_corner_attributes(attributes,
in_component,
out_component,
- num_selected_loops,
+ selected_loops_num,
selected_poly_indices,
mesh_in);
break;
@@ -1172,8 +1172,8 @@ static void do_mesh_separation(GeometrySet &geometry_set,
invert,
selected_poly_indices,
new_loop_starts,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_EDGE:
compute_selected_polygons_from_edge_selection(mesh_in,
@@ -1181,8 +1181,8 @@ static void do_mesh_separation(GeometrySet &geometry_set,
invert,
selected_poly_indices,
new_loop_starts,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_polys_num,
+ &selected_loops_num);
break;
case ATTR_DOMAIN_FACE:
compute_selected_polygons_from_poly_selection(mesh_in,
@@ -1190,15 +1190,15 @@ static void do_mesh_separation(GeometrySet &geometry_set,
invert,
selected_poly_indices,
new_loop_starts,
- &num_selected_polys,
- &num_selected_loops);
+ &selected_polys_num,
+ &selected_loops_num);
break;
default:
BLI_assert_unreachable();
break;
}
mesh_out = BKE_mesh_new_nomain_from_template(
- &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, num_selected_loops, num_selected_polys);
+ &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
@@ -1217,7 +1217,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_face_corner_attributes(attributes,
in_component,
out_component,
- num_selected_loops,
+ selected_loops_num,
selected_poly_indices,
mesh_in);
break;
diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
index 39e5748daa5..2aa768129cd 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc
@@ -60,18 +60,16 @@ struct IndexAttributes {
/** \name Utility Functions
* \{ */
-static void gather_attributes_without_id(const GeometrySet &geometry_set,
- const GeometryComponentType component_type,
- const Span<std::string> skip_attributes,
- const bool include_instances,
- Map<AttributeIDRef, AttributeKind> &r_gathered_attributes)
+static Map<AttributeIDRef, AttributeKind> gather_attributes_without_id(
+ const GeometrySet &geometry_set,
+ const GeometryComponentType component_type,
+ const bool include_instances)
{
+ Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
- {component_type}, component_type, include_instances, r_gathered_attributes);
- for (const std::string &attribute : skip_attributes) {
- r_gathered_attributes.remove(attribute);
- }
- r_gathered_attributes.remove("id");
+ {component_type}, component_type, include_instances, attributes);
+ attributes.remove("id");
+ return attributes;
};
static IndexRange range_for_offsets_index(const Span<int> offsets, const int index)
@@ -83,12 +81,12 @@ static Array<int> accumulate_counts_to_offsets(const IndexMask selection,
const VArray<int> &counts)
{
Array<int> offsets(selection.size() + 1);
- int dst_points_size = 0;
- for (const int i_point : selection.index_range()) {
- offsets[i_point] = dst_points_size;
- dst_points_size += std::max(counts[selection[i_point]], 0);
+ int total = 0;
+ for (const int i : selection.index_range()) {
+ offsets[i] = total;
+ total += std::max(counts[selection[i]], 0);
}
- offsets.last() = dst_points_size;
+ offsets.last() = total;
return offsets;
}
@@ -141,11 +139,11 @@ static void threaded_id_offset_copy(const Span<int> offsets,
static void create_duplicate_index_attribute(GeometryComponent &component,
const AttributeDomain output_domain,
const IndexMask selection,
- const IndexAttributes &attributes,
+ const IndexAttributes &attribute_outputs,
const Span<int> offsets)
{
OutputAttribute_Typed<int> copy_attribute = component.attribute_try_get_for_output_only<int>(
- attributes.duplicate_index.get(), output_domain);
+ attribute_outputs.duplicate_index.get(), output_domain);
MutableSpan<int> duplicate_indices = copy_attribute.as_span();
for (const int i : IndexRange(selection.size())) {
const IndexRange range = range_for_offsets_index(offsets, i);
@@ -193,11 +191,10 @@ static void copy_point_attributes_without_id(GeometrySet &geometry_set,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
{
- Map<AttributeIDRef, AttributeKind> gathered_attributes;
- gather_attributes_without_id(
- geometry_set, component_type, {}, include_instances, gathered_attributes);
+ Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
+ geometry_set, component_type, include_instances);
- for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) {
+ for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
if (!src_attribute || src_attribute.domain != ATTR_DOMAIN_POINT) {
@@ -239,12 +236,10 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
bke::CurvesGeometry &dst_curves,
CurveComponent &dst_component)
{
- Map<AttributeIDRef, AttributeKind> gathered_attributes;
- gather_attributes_without_id(
- geometry_set, GEO_COMPONENT_TYPE_CURVE, {}, false, gathered_attributes);
-
- for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) {
+ Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
+ geometry_set, GEO_COMPONENT_TYPE_CURVE, false);
+ for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
if (!src_attribute) {
@@ -273,9 +268,9 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
const int i_src_curve = selection[i_selection];
- const Span<T> curve_src = src.slice(src_curves.range_for_curve(i_src_curve));
+ const Span<T> curve_src = src.slice(src_curves.points_for_curve(i_src_curve));
for (const int i_dst_curve : range_for_offsets_index(curve_offsets, i_selection)) {
- dst.slice(dst_curves.range_for_curve(i_dst_curve)).copy_from(curve_src);
+ dst.slice(dst_curves.points_for_curve(i_dst_curve)).copy_from(curve_src);
}
}
});
@@ -317,12 +312,12 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
const int i_src_curve = selection[i_selection];
- const Span<int> curve_src = src.slice(src_curves.range_for_curve(i_src_curve));
+ const Span<int> curve_src = src.slice(src_curves.points_for_curve(i_src_curve));
const IndexRange duplicates_range = range_for_offsets_index(curve_offsets, i_selection);
for (const int i_duplicate : IndexRange(duplicates_range.size()).drop_front(1)) {
const int i_dst_curve = duplicates_range[i_duplicate];
copy_hashed_ids(
- curve_src, i_duplicate, dst.slice(dst_curves.range_for_curve(i_dst_curve)));
+ curve_src, i_duplicate, dst.slice(dst_curves.points_for_curve(i_dst_curve)));
}
}
});
@@ -332,7 +327,7 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
static void duplicate_curves(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_curves()) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
@@ -345,7 +340,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_CURVE};
- FieldEvaluator evaluator{field_context, curves.curves_size()};
+ FieldEvaluator evaluator{field_context, curves.curves_num()};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@@ -363,7 +358,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
curve_offsets[i_curve] = dst_curves_size;
point_offsets[i_curve] = dst_points_size;
dst_curves_size += count;
- dst_points_size += count * curves.range_for_curve(selection[i_curve]).size();
+ dst_points_size += count * curves.points_for_curve(selection[i_curve]).size();
}
curve_offsets.last() = dst_curves_size;
point_offsets.last() = dst_points_size;
@@ -375,7 +370,7 @@ static void duplicate_curves(GeometrySet &geometry_set,
threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) {
for (const int i_selection : range) {
const int i_src_curve = selection[i_selection];
- const IndexRange src_curve_range = curves.range_for_curve(i_src_curve);
+ const IndexRange src_curve_range = curves.points_for_curve(i_src_curve);
const IndexRange dst_curves_range = range_for_offsets_index(curve_offsets, i_selection);
MutableSpan<int> dst_offsets = all_dst_offsets.slice(dst_curves_range);
for (const int i_duplicate : IndexRange(dst_curves_range.size())) {
@@ -395,9 +390,9 @@ static void duplicate_curves(GeometrySet &geometry_set,
copy_stable_id_curves(
curves, selection, curve_offsets, src_component, new_curves, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_CURVE, selection, attributes, curve_offsets);
+ dst_component, ATTR_DOMAIN_CURVE, selection, attribute_outputs, curve_offsets);
}
geometry_set.replace_curves(new_curves_id);
@@ -421,11 +416,10 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
{
- Map<AttributeIDRef, AttributeKind> gathered_attributes;
- gather_attributes_without_id(
- geometry_set, GEO_COMPONENT_TYPE_MESH, {}, false, gathered_attributes);
+ Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
+ geometry_set, GEO_COMPONENT_TYPE_MESH, false);
- for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) {
+ for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
if (!src_attribute) {
@@ -521,7 +515,7 @@ static void copy_stable_id_faces(const Mesh &mesh,
static void duplicate_faces(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_mesh()) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
@@ -609,9 +603,9 @@ static void duplicate_faces(GeometrySet &geometry_set,
copy_stable_id_faces(mesh, selection, offsets, vert_mapping, src_component, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_FACE, selection, attributes, offsets);
+ dst_component, ATTR_DOMAIN_FACE, selection, attribute_outputs, offsets);
}
geometry_set.replace_mesh(new_mesh);
@@ -633,11 +627,10 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
{
- Map<AttributeIDRef, AttributeKind> gathered_attributes;
- gather_attributes_without_id(
- geometry_set, GEO_COMPONENT_TYPE_MESH, {}, false, gathered_attributes);
+ Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
+ geometry_set, GEO_COMPONENT_TYPE_MESH, false);
- for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) {
+ for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
if (!src_attribute) {
@@ -719,7 +712,7 @@ static void copy_stable_id_edges(const Mesh &mesh,
static void duplicate_edges(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_mesh()) {
geometry_set.keep_only({GEO_COMPONENT_TYPE_INSTANCES});
@@ -778,9 +771,9 @@ static void duplicate_edges(GeometrySet &geometry_set,
copy_stable_id_edges(mesh, selection, edge_offsets, src_component, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_EDGE, selection, attributes, edge_offsets);
+ dst_component, ATTR_DOMAIN_EDGE, selection, attribute_outputs, edge_offsets);
}
geometry_set.replace_mesh(new_mesh);
@@ -795,17 +788,17 @@ static void duplicate_edges(GeometrySet &geometry_set,
static void duplicate_points_curve(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
const CurveComponent &src_component = *geometry_set.get_component_for_read<CurveComponent>();
const Curves &src_curves_id = *src_component.get_for_read();
const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry);
- if (src_curves.points_size() == 0) {
+ if (src_curves.points_num() == 0) {
return;
}
GeometryComponentFieldContext field_context{src_component, ATTR_DOMAIN_POINT};
- FieldEvaluator evaluator{field_context, src_curves.points_size()};
+ FieldEvaluator evaluator{field_context, src_curves.points_num()};
evaluator.add(count_field);
evaluator.set_selection(selection_field);
evaluator.evaluate();
@@ -815,10 +808,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
Array<int> offsets = accumulate_counts_to_offsets(selection, counts);
const int dst_size = offsets.last();
- Array<int> point_to_curve_map(src_curves.points_size());
+ Array<int> point_to_curve_map(src_curves.points_num());
threading::parallel_for(src_curves.curves_range(), 1024, [&](const IndexRange range) {
for (const int i_curve : range) {
- const IndexRange point_range = src_curves.range_for_curve(i_curve);
+ const IndexRange point_range = src_curves.points_for_curve(i_curve);
point_to_curve_map.as_mutable_span().slice(point_range).fill(i_curve);
}
});
@@ -834,11 +827,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
CurveComponent dst_component;
dst_component.replace(new_curves_id, GeometryOwnershipType::Editable);
- Map<AttributeIDRef, AttributeKind> gathered_attributes;
- gather_attributes_without_id(
- geometry_set, GEO_COMPONENT_TYPE_CURVE, {}, false, gathered_attributes);
+ Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
+ geometry_set, GEO_COMPONENT_TYPE_CURVE, false);
- for (const Map<AttributeIDRef, AttributeKind>::Item entry : gathered_attributes.items()) {
+ for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
ReadAttributeLookup src_attribute = src_component.attribute_try_get_for_read(attribute_id);
if (!src_attribute) {
@@ -881,9 +873,9 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
copy_stable_id_point(offsets, src_component, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets.as_span());
+ dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span());
}
geometry_set.replace_curves(new_curves_id);
@@ -898,7 +890,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
static void duplicate_points_mesh(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
const MeshComponent &src_component = *geometry_set.get_component_for_read<MeshComponent>();
const Mesh &mesh = *geometry_set.get_mesh_for_read();
@@ -926,9 +918,9 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
copy_stable_id_point(offsets, src_component, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets.as_span());
+ dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span());
}
geometry_set.replace_mesh(new_mesh);
@@ -943,7 +935,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
static void duplicate_points_pointcloud(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
const PointCloudComponent &src_points =
*geometry_set.get_component_for_read<PointCloudComponent>();
@@ -968,9 +960,9 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
copy_stable_id_point(offsets, src_points, dst_component);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_component, ATTR_DOMAIN_POINT, selection, attributes, offsets);
+ dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets);
}
geometry_set.replace_pointcloud(pointcloud);
}
@@ -984,24 +976,25 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
static void duplicate_points(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
Vector<GeometryComponentType> component_types = geometry_set.gather_component_types(true, true);
for (const GeometryComponentType component_type : component_types) {
switch (component_type) {
case GEO_COMPONENT_TYPE_POINT_CLOUD:
if (geometry_set.has_pointcloud()) {
- duplicate_points_pointcloud(geometry_set, count_field, selection_field, attributes);
+ duplicate_points_pointcloud(
+ geometry_set, count_field, selection_field, attribute_outputs);
}
break;
case GEO_COMPONENT_TYPE_MESH:
if (geometry_set.has_mesh()) {
- duplicate_points_mesh(geometry_set, count_field, selection_field, attributes);
+ duplicate_points_mesh(geometry_set, count_field, selection_field, attribute_outputs);
}
break;
case GEO_COMPONENT_TYPE_CURVE:
if (geometry_set.has_curves()) {
- duplicate_points_curve(geometry_set, count_field, selection_field, attributes);
+ duplicate_points_curve(geometry_set, count_field, selection_field, attribute_outputs);
}
break;
default:
@@ -1021,7 +1014,7 @@ static void duplicate_points(GeometrySet &geometry_set,
static void duplicate_instances(GeometrySet &geometry_set,
const Field<int> &count_field,
const Field<bool> &selection_field,
- const IndexAttributes &attributes)
+ const IndexAttributes &attribute_outputs)
{
if (!geometry_set.has_instances()) {
geometry_set.clear();
@@ -1064,9 +1057,9 @@ static void duplicate_instances(GeometrySet &geometry_set,
copy_point_attributes_without_id(
geometry_set, GEO_COMPONENT_TYPE_INSTANCES, true, offsets, src_instances, dst_instances);
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
- dst_instances, ATTR_DOMAIN_INSTANCE, selection, attributes, offsets);
+ dst_instances, ATTR_DOMAIN_INSTANCE, selection, attribute_outputs, offsets);
}
geometry_set = std::move(dst_geometry);
@@ -1087,28 +1080,28 @@ static void node_geo_exec(GeoNodeExecParams params)
Field<int> count_field = params.extract_input<Field<int>>("Amount");
Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
- IndexAttributes attributes;
+ IndexAttributes attribute_outputs;
if (params.output_is_required("Duplicate Index")) {
- attributes.duplicate_index = StrongAnonymousAttributeID("duplicate_index");
+ attribute_outputs.duplicate_index = StrongAnonymousAttributeID("duplicate_index");
}
if (duplicate_domain == ATTR_DOMAIN_INSTANCE) {
- duplicate_instances(geometry_set, count_field, selection_field, attributes);
+ duplicate_instances(geometry_set, count_field, selection_field, attribute_outputs);
}
else {
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
switch (duplicate_domain) {
case ATTR_DOMAIN_CURVE:
- duplicate_curves(geometry_set, count_field, selection_field, attributes);
+ duplicate_curves(geometry_set, count_field, selection_field, attribute_outputs);
break;
case ATTR_DOMAIN_FACE:
- duplicate_faces(geometry_set, count_field, selection_field, attributes);
+ duplicate_faces(geometry_set, count_field, selection_field, attribute_outputs);
break;
case ATTR_DOMAIN_EDGE:
- duplicate_edges(geometry_set, count_field, selection_field, attributes);
+ duplicate_edges(geometry_set, count_field, selection_field, attribute_outputs);
break;
case ATTR_DOMAIN_POINT:
- duplicate_points(geometry_set, count_field, selection_field, attributes);
+ duplicate_points(geometry_set, count_field, selection_field, attribute_outputs);
break;
default:
BLI_assert_unreachable();
@@ -1122,10 +1115,10 @@ static void node_geo_exec(GeoNodeExecParams params)
return;
}
- if (attributes.duplicate_index) {
+ if (attribute_outputs.duplicate_index) {
params.set_output(
"Duplicate Index",
- AnonymousAttributeFieldInput::Create<int>(std::move(attributes.duplicate_index),
+ AnonymousAttributeFieldInput::Create<int>(std::move(attribute_outputs.duplicate_index),
params.attribute_producer_name()));
}
params.set_output("Geometry", std::move(geometry_set));
diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
index 197cb6e6852..ab6f6b40d5e 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc
@@ -86,13 +86,13 @@ static VArray<int> construct_spline_count_gvarray(const CurveComponent &componen
const Curves &curves_id = *component.get_for_read();
const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry);
- auto count_fn = [curves](int64_t i) { return curves.range_for_curve(i).size(); };
+ auto count_fn = [curves](int64_t i) { return curves.points_for_curve(i).size(); };
if (domain == ATTR_DOMAIN_CURVE) {
- return VArray<int>::ForFunc(curves.curves_size(), count_fn);
+ return VArray<int>::ForFunc(curves.curves_num(), count_fn);
}
if (domain == ATTR_DOMAIN_POINT) {
- VArray<int> count = VArray<int>::ForFunc(curves.curves_size(), count_fn);
+ VArray<int> count = VArray<int>::ForFunc(curves.curves_num(), count_fn);
return component.attribute_try_adapt_domain<int>(
std::move(count), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT);
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
index a04544e2814..cc115ee3b3f 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc
@@ -103,8 +103,8 @@ static void transform_volume(Volume &volume, const float4x4 &transform, const De
memcpy(vdb_matrix.asPointer(), &scale_limited_transform, sizeof(float[4][4]));
openvdb::Mat4d vdb_matrix_d{vdb_matrix};
- const int num_grids = BKE_volume_num_grids(&volume);
- for (const int i : IndexRange(num_grids)) {
+ const int grids_num = BKE_volume_num_grids(&volume);
+ for (const int i : IndexRange(grids_num)) {
VolumeGrid *volume_grid = BKE_volume_grid_get_for_write(&volume, i);
openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(&volume, volume_grid, false);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
index a5ab6db0002..f5a4d087dbd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc
@@ -239,7 +239,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
return;
}
if (params.node_tree().typeinfo->validate_link(
- static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
+ static_cast<eNodeSocketDatatype>(params.other_socket().type), SOCK_FLOAT)) {
params.add_item(IFACE_("Vector"), [](LinkSearchOpParams &params) {
bNode &node = params.add_node("ShaderNodeTexSky");
NodeTexSky *tex = (NodeTexSky *)node.storage;
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 6492f528a5e..35d5cb6a994 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -233,8 +233,8 @@ static int bpy_slot_from_py(BMesh *bm,
if (!Matrix_ParseAny(value, &pymat)) {
return -1;
}
- const ushort size = pymat->num_col;
- if ((size != pymat->num_row) || (!ELEM(size, 3, 4))) {
+ const ushort size = pymat->col_num;
+ if ((size != pymat->row_num) || (!ELEM(size, 3, 4))) {
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" expected a 3x3 or 4x4 matrix",
opname,
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 9ceff9b84b6..46f89dd4103 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -1309,7 +1309,7 @@ static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject
if (BaseMath_ReadCallback(mat) == -1) {
return NULL;
}
- if (mat->num_col != 4 || mat->num_row != 4) {
+ if (mat->col_num != 4 || mat->row_num != 4) {
PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix");
return NULL;
}
diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c
index 3fbfd1655c5..9e45105d105 100644
--- a/source/blender/python/generic/blf_py_api.c
+++ b/source/blender/python/generic/blf_py_api.c
@@ -396,41 +396,41 @@ static PyObject *py_blf_shadow_offset(PyObject *UNUSED(self), PyObject *args)
}
PyDoc_STRVAR(py_blf_load_doc,
- ".. function:: load(filename)\n"
+ ".. function:: load(filepath)\n"
"\n"
" Load a new font.\n"
"\n"
- " :arg filename: the filename of the font.\n"
- " :type filename: string\n"
+ " :arg filepath: the filepath of the font.\n"
+ " :type filepath: string\n"
" :return: the new font's fontid or -1 if there was an error.\n"
" :rtype: integer\n");
static PyObject *py_blf_load(PyObject *UNUSED(self), PyObject *args)
{
- const char *filename;
+ const char *filepath;
- if (!PyArg_ParseTuple(args, "s:blf.load", &filename)) {
+ if (!PyArg_ParseTuple(args, "s:blf.load", &filepath)) {
return NULL;
}
- return PyLong_FromLong(BLF_load(filename));
+ return PyLong_FromLong(BLF_load(filepath));
}
PyDoc_STRVAR(py_blf_unload_doc,
- ".. function:: unload(filename)\n"
+ ".. function:: unload(filepath)\n"
"\n"
" Unload an existing font.\n"
"\n"
- " :arg filename: the filename of the font.\n"
- " :type filename: string\n");
+ " :arg filepath: the filepath of the font.\n"
+ " :type filepath: string\n");
static PyObject *py_blf_unload(PyObject *UNUSED(self), PyObject *args)
{
- const char *filename;
+ const char *filepath;
- if (!PyArg_ParseTuple(args, "s:blf.unload", &filename)) {
+ if (!PyArg_ParseTuple(args, "s:blf.unload", &filepath)) {
return NULL;
}
- BLF_unload(filename);
+ BLF_unload(filepath);
Py_RETURN_NONE;
}
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index 1a53ccd6686..43b26e05327 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -381,11 +381,11 @@ static PyObject *pygpu_shader_uniform_float(BPyGPUShader *self, PyObject *args)
if (BaseMath_ReadCallback(mat) == -1) {
return NULL;
}
- if ((mat->num_row != mat->num_col) || !ELEM(mat->num_row, 3, 4)) {
+ if ((mat->row_num != mat->col_num) || !ELEM(mat->row_num, 3, 4)) {
PyErr_SetString(PyExc_ValueError, "Expected 3x3 or 4x4 matrix");
return NULL;
}
- length = mat->num_row * mat->num_col;
+ length = mat->row_num * mat->col_num;
memcpy(values, mat->matrix, sizeof(float) * length);
}
else {
diff --git a/source/blender/python/gpu/gpu_py_state.c b/source/blender/python/gpu/gpu_py_state.c
index e3ffd3cc823..fb69bb316c4 100644
--- a/source/blender/python/gpu/gpu_py_state.c
+++ b/source/blender/python/gpu/gpu_py_state.c
@@ -347,7 +347,7 @@ static PyObject *pygpu_state_program_point_size_set(PyObject *UNUSED(self), PyOb
PyDoc_STRVAR(pygpu_state_framebuffer_active_get_doc,
".. function:: framebuffer_active_get(enable)\n"
"\n"
- " Return the active framefuffer in context.\n");
+ " Return the active frame-buffer in context.\n");
static PyObject *pygpu_state_framebuffer_active_get(PyObject *UNUSED(self))
{
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index a35f03f9872..f813a006c7e 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -224,6 +224,10 @@ if(WITH_IMAGE_TIFF)
add_definitions(-DWITH_TIFF)
endif()
+if(WITH_WEBP)
+ add_definitions(-DWITH_WEBP)
+endif()
+
if(WITH_INPUT_NDOF)
add_definitions(-DWITH_INPUT_NDOF)
endif()
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index ba3e6a3d74b..34ffef03e66 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -24,7 +24,7 @@
void bpy_app_generic_callback(struct Main *main,
struct PointerRNA **pointers,
- const int num_pointers,
+ const int pointers_num,
void *arg);
static PyTypeObject BlenderAppCbType;
@@ -305,7 +305,7 @@ static PyObject *choose_arguments(PyObject *func, PyObject *args_all, PyObject *
/* the actual callback - not necessarily called from py */
void bpy_app_generic_callback(struct Main *UNUSED(main),
struct PointerRNA **pointers,
- const int num_pointers,
+ const int pointers_num,
void *arg)
{
PyObject *cb_list = py_cb_array[POINTER_AS_INT(arg)];
@@ -320,14 +320,14 @@ void bpy_app_generic_callback(struct Main *UNUSED(main),
Py_ssize_t pos;
/* setup arguments */
- for (int i = 0; i < num_pointers; ++i) {
+ for (int i = 0; i < pointers_num; ++i) {
PyTuple_SET_ITEM(args_all, i, pyrna_struct_CreatePyObject(pointers[i]));
}
- for (int i = num_pointers; i < num_arguments; ++i) {
+ for (int i = pointers_num; i < num_arguments; ++i) {
PyTuple_SET_ITEM(args_all, i, Py_INCREF_RET(Py_None));
}
- if (num_pointers == 0) {
+ if (pointers_num == 0) {
PyTuple_SET_ITEM(args_single, 0, Py_INCREF_RET(Py_None));
}
else {
diff --git a/source/blender/python/intern/bpy_interface_run.c b/source/blender/python/intern/bpy_interface_run.c
index 8db122470b8..9299bd196e2 100644
--- a/source/blender/python/intern/bpy_interface_run.c
+++ b/source/blender/python/intern/bpy_interface_run.c
@@ -35,22 +35,33 @@
/** \name Private Utilities
* \{ */
-static void python_script_error_jump_text(Text *text)
+static void python_script_error_jump_text(Text *text, const char *filepath)
{
- int lineno;
- int offset;
- python_script_error_jump(text->id.name + 2, &lineno, &offset);
- if (lineno != -1) {
- /* select the line with the error */
- txt_move_to(text, lineno - 1, INT_MAX, false);
+ int lineno, lineno_end;
+ int offset, offset_end;
+ if (python_script_error_jump(filepath, &lineno, &offset, &lineno_end, &offset_end)) {
+ /* Start at the end so cursor motion that looses the selection,
+ * leaves the cursor from the most useful place.
+ * Also, the end can't always be set, so don't give it priority. */
+ txt_move_to(text, lineno_end - 1, offset_end, false);
txt_move_to(text, lineno - 1, offset, true);
}
}
-/* returns a dummy filename for a textblock so we can tell what file a text block comes from */
-static void bpy_text_filename_get(char *fn, const Main *bmain, size_t fn_len, const Text *text)
+/**
+ * Generate a `filepath` from a text-block so we can tell what file a text block comes from.
+ */
+static void bpy_text_filepath_get(char *filepath,
+ const size_t filepath_maxlen,
+ const Main *bmain,
+ const Text *text)
{
- BLI_snprintf(fn, fn_len, "%s%c%s", ID_BLEND_PATH(bmain, &text->id), SEP, text->id.name + 2);
+ BLI_snprintf(filepath,
+ filepath_maxlen,
+ "%s%c%s",
+ ID_BLEND_PATH(bmain, &text->id),
+ SEP,
+ text->id.name + 2);
}
/* Very annoying! Undo #_PyModule_Clear(), see T23871. */
@@ -74,17 +85,24 @@ typedef struct {
*
* \note Share a function for this since setup/cleanup logic is the same.
*/
-static bool python_script_exec(
- bContext *C, const char *fn, struct Text *text, struct ReportList *reports, const bool do_jump)
+static bool python_script_exec(bContext *C,
+ const char *filepath,
+ struct Text *text,
+ struct ReportList *reports,
+ const bool do_jump)
{
Main *bmain_old = CTX_data_main(C);
PyObject *main_mod = NULL;
PyObject *py_dict = NULL, *py_result = NULL;
PyGILState_STATE gilstate;
- BLI_assert(fn || text);
+ char filepath_dummy[FILE_MAX];
+ /** The `__file__` added into the name-space. */
+ const char *filepath_namespace = NULL;
+
+ BLI_assert(filepath || text);
- if (fn == NULL && text == NULL) {
+ if (filepath == NULL && text == NULL) {
return 0;
}
@@ -93,40 +111,41 @@ static bool python_script_exec(
PyC_MainModule_Backup(&main_mod);
if (text) {
- char fn_dummy[FILE_MAXDIR];
- bpy_text_filename_get(fn_dummy, bmain_old, sizeof(fn_dummy), text);
+ bpy_text_filepath_get(filepath_dummy, sizeof(filepath_dummy), bmain_old, text);
+ filepath_namespace = filepath_dummy;
if (text->compiled == NULL) { /* if it wasn't already compiled, do it now */
char *buf;
- PyObject *fn_dummy_py;
+ PyObject *filepath_dummy_py;
- fn_dummy_py = PyC_UnicodeFromByte(fn_dummy);
+ filepath_dummy_py = PyC_UnicodeFromByte(filepath_dummy);
size_t buf_len_dummy;
buf = txt_to_buf(text, &buf_len_dummy);
- text->compiled = Py_CompileStringObject(buf, fn_dummy_py, Py_file_input, NULL, -1);
+ text->compiled = Py_CompileStringObject(buf, filepath_dummy_py, Py_file_input, NULL, -1);
MEM_freeN(buf);
- Py_DECREF(fn_dummy_py);
+ Py_DECREF(filepath_dummy_py);
if (PyErr_Occurred()) {
if (do_jump) {
- python_script_error_jump_text(text);
+ python_script_error_jump_text(text, filepath_dummy);
}
BPY_text_free_code(text);
}
}
if (text->compiled) {
- py_dict = PyC_DefaultNameSpace(fn_dummy);
+ py_dict = PyC_DefaultNameSpace(filepath_dummy);
py_result = PyEval_EvalCode(text->compiled, py_dict, py_dict);
}
}
else {
- FILE *fp = BLI_fopen(fn, "r");
+ FILE *fp = BLI_fopen(filepath, "r");
+ filepath_namespace = filepath;
if (fp) {
- py_dict = PyC_DefaultNameSpace(fn);
+ py_dict = PyC_DefaultNameSpace(filepath);
#ifdef _WIN32
/* Previously we used PyRun_File to run directly the code on a FILE
@@ -153,13 +172,13 @@ static bool python_script_exec(
py_result = PyRun_String(pystring, Py_file_input, py_dict, py_dict);
}
#else
- py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
+ py_result = PyRun_File(fp, filepath, Py_file_input, py_dict, py_dict);
fclose(fp);
#endif
}
else {
PyErr_Format(
- PyExc_IOError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
+ PyExc_IOError, "Python file \"%s\" could not be opened: %s", filepath, strerror(errno));
py_result = NULL;
}
}
@@ -170,7 +189,7 @@ static bool python_script_exec(
/* ensure text is valid before use, the script may have freed itself */
Main *bmain_new = CTX_data_main(C);
if ((bmain_old == bmain_new) && (BLI_findindex(&bmain_new->texts, text) != -1)) {
- python_script_error_jump_text(text);
+ python_script_error_jump_text(text, filepath_namespace);
}
}
}
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index f5bec247250..8506ec97bc3 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -377,15 +377,15 @@ static int validate_array(PyObject *rvalue,
totdim);
return -1;
}
- if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) {
+ if (pymat->col_num != dimsize[0] || pymat->row_num != dimsize[1]) {
PyErr_Format(PyExc_ValueError,
"%s %.200s.%.200s, matrix assign dimension size mismatch, "
"is %dx%d, expected be %dx%d",
error_prefix,
RNA_struct_identifier(ptr->type),
RNA_property_identifier(prop),
- pymat->num_col,
- pymat->num_row,
+ pymat->col_num,
+ pymat->row_num,
dimsize[0],
dimsize[1]);
return -1;
@@ -473,7 +473,7 @@ static char *copy_values(PyObject *seq,
if (dim == 0) {
if (MatrixObject_Check(seq)) {
MatrixObject *pymat = (MatrixObject *)seq;
- const size_t allocsize = pymat->num_col * pymat->num_row * sizeof(float);
+ const size_t allocsize = pymat->col_num * pymat->row_num * sizeof(float);
/* read callback already done by validate */
/* since this is the first iteration we can assume data is allocated */
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 13af254c286..40478f3613c 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -24,7 +24,7 @@ static const char *traceback_filepath(PyTracebackObject *tb, PyObject **coerce)
return PyBytes_AS_STRING(*coerce);
}
-/* copied from pythonrun.c, 3.4.0 */
+/* copied from pythonrun.c, 3.10.0 */
_Py_static_string(PyId_string, "<string>");
static int parse_syntax_error(PyObject *err,
@@ -32,14 +32,18 @@ static int parse_syntax_error(PyObject *err,
PyObject **filename,
int *lineno,
int *offset,
+ int *end_lineno,
+ int *end_offset,
PyObject **text)
{
- long hold;
+ Py_ssize_t hold;
PyObject *v;
_Py_IDENTIFIER(msg);
_Py_IDENTIFIER(filename);
_Py_IDENTIFIER(lineno);
_Py_IDENTIFIER(offset);
+ _Py_IDENTIFIER(end_lineno);
+ _Py_IDENTIFIER(end_offset);
_Py_IDENTIFIER(text);
*message = NULL;
@@ -71,7 +75,7 @@ static int parse_syntax_error(PyObject *err,
if (!v) {
goto finally;
}
- hold = PyLong_AsLong(v);
+ hold = PyLong_AsSsize_t(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred()) {
goto finally;
@@ -87,7 +91,7 @@ static int parse_syntax_error(PyObject *err,
Py_DECREF(v);
}
else {
- hold = PyLong_AsLong(v);
+ hold = PyLong_AsSsize_t(v);
Py_DECREF(v);
if (hold < 0 && PyErr_Occurred()) {
goto finally;
@@ -95,6 +99,49 @@ static int parse_syntax_error(PyObject *err,
*offset = (int)hold;
}
+ if (Py_TYPE(err) == (PyTypeObject *)PyExc_SyntaxError) {
+ v = _PyObject_GetAttrId(err, &PyId_end_lineno);
+ if (!v) {
+ PyErr_Clear();
+ *end_lineno = *lineno;
+ }
+ else if (v == Py_None) {
+ *end_lineno = *lineno;
+ Py_DECREF(v);
+ }
+ else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred()) {
+ goto finally;
+ }
+ *end_lineno = hold;
+ }
+
+ v = _PyObject_GetAttrId(err, &PyId_end_offset);
+ if (!v) {
+ PyErr_Clear();
+ *end_offset = -1;
+ }
+ else if (v == Py_None) {
+ *end_offset = -1;
+ Py_DECREF(v);
+ }
+ else {
+ hold = PyLong_AsSsize_t(v);
+ Py_DECREF(v);
+ if (hold < 0 && PyErr_Occurred()) {
+ goto finally;
+ }
+ *end_offset = hold;
+ }
+ }
+ else {
+ /* `SyntaxError` subclasses. */
+ *end_lineno = *lineno;
+ *end_offset = -1;
+ }
+
v = _PyObject_GetAttrId(err, &PyId_text);
if (!v) {
goto finally;
@@ -115,39 +162,48 @@ finally:
}
/* end copied function! */
-void python_script_error_jump(const char *filepath, int *lineno, int *offset)
+bool python_script_error_jump(
+ const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end)
{
+ bool success = false;
PyObject *exception, *value;
PyTracebackObject *tb;
- *lineno = -1;
- *offset = 0;
+ *r_lineno = -1;
+ *r_offset = 0;
+
+ *r_lineno_end = -1;
+ *r_offset_end = 0;
PyErr_Fetch(&exception, &value, (PyObject **)&tb);
+ if (exception == NULL) {
+ return false;
+ }
- if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
- /* no trace-back available when `SyntaxError`.
- * python has no API's to this. reference #parse_syntax_error() from pythonrun.c */
+ if (PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
+ /* 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 */
+ if (value) { /* Should always be true. */
PyObject *message;
- PyObject *filename_py, *text_py;
-
- if (parse_syntax_error(value, &message, &filename_py, lineno, offset, &text_py)) {
- const char *filename = PyUnicode_AsUTF8(filename_py);
+ PyObject *filepath_exc_py, *text_py;
+
+ if (parse_syntax_error(value,
+ &message,
+ &filepath_exc_py,
+ r_lineno,
+ r_offset,
+ r_lineno_end,
+ r_offset_end,
+ &text_py)) {
+ const char *filepath_exc = PyUnicode_AsUTF8(filepath_exc_py);
/* python adds a '/', prefix, so check for both */
- if ((BLI_path_cmp(filename, filepath) == 0) ||
- (ELEM(filename[0], '\\', '/') && BLI_path_cmp(filename + 1, filepath) == 0)) {
- /* good */
- }
- else {
- *lineno = -1;
+ if ((BLI_path_cmp(filepath_exc, filepath) == 0) ||
+ (ELEM(filepath_exc[0], '\\', '/') && BLI_path_cmp(filepath_exc + 1, filepath) == 0)) {
+ success = true;
}
}
- else {
- *lineno = -1;
- }
}
PyErr_Restore(exception, value, (PyObject *)tb); /* takes away reference! */
}
@@ -167,9 +223,12 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset)
Py_DECREF(coerce);
if (match) {
- *lineno = tb->tb_lineno;
+ success = true;
+ *r_lineno = *r_lineno_end = tb->tb_lineno;
/* used to break here, but better find the inner most line */
}
}
}
+
+ return success;
}
diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h
index 99e032f3594..f5232eca864 100644
--- a/source/blender/python/intern/bpy_traceback.h
+++ b/source/blender/python/intern/bpy_traceback.h
@@ -10,7 +10,8 @@
extern "C" {
#endif
-void python_script_error_jump(const char *filepath, int *lineno, int *offset);
+bool python_script_error_jump(
+ const char *filepath, int *r_lineno, int *r_offset, int *r_lineno_end, int *r_offset_end);
#ifdef __cplusplus
}
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 8ed156a7e55..1aa2cec861c 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -92,47 +92,46 @@ Py_hash_t mathutils_array_hash(const float *array, size_t array_len)
}
int mathutils_array_parse(
- float *array, int array_min, int array_max, PyObject *value, const char *error_prefix)
+ float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix)
{
- const uint flag = array_max;
- int size;
+ const uint flag = array_num_max;
+ int num;
- array_max &= ~MU_ARRAY_FLAGS;
+ array_num_max &= ~MU_ARRAY_FLAGS;
#if 1 /* approx 6x speedup for mathutils types */
- if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
- (size = EulerObject_Check(value) ? 3 : 0) ||
- (size = QuaternionObject_Check(value) ? 4 : 0) ||
- (size = ColorObject_Check(value) ? 3 : 0)) {
+ if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||
+ (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||
+ (num = ColorObject_Check(value) ? 3 : 0)) {
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
if (flag & MU_ARRAY_SPILL) {
- CLAMP_MAX(size, array_max);
+ CLAMP_MAX(num, array_num_max);
}
- if (size > array_max || size < array_min) {
- if (array_max == array_min) {
+ if (num > array_num_max || num < array_num_min) {
+ if (array_num_max == array_num_min) {
PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected %d",
+ "%.200s: sequence length is %d, expected %d",
error_prefix,
- size,
- array_max);
+ num,
+ array_num_max);
}
else {
PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected [%d - %d]",
+ "%.200s: sequence length is %d, expected [%d - %d]",
error_prefix,
- size,
- array_min,
- array_max);
+ num,
+ array_num_min,
+ array_num_max);
}
return -1;
}
- memcpy(array, ((const BaseMathObject *)value)->data, size * sizeof(float));
+ memcpy(array, ((const BaseMathObject *)value)->data, num * sizeof(float));
}
else
#endif
@@ -145,77 +144,76 @@ int mathutils_array_parse(
return -1;
}
- size = PySequence_Fast_GET_SIZE(value_fast);
+ num = PySequence_Fast_GET_SIZE(value_fast);
if (flag & MU_ARRAY_SPILL) {
- CLAMP_MAX(size, array_max);
+ CLAMP_MAX(num, array_num_max);
}
- if (size > array_max || size < array_min) {
- if (array_max == array_min) {
+ if (num > array_num_max || num < array_num_min) {
+ if (array_num_max == array_num_min) {
PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected %d",
+ "%.200s: sequence length is %d, expected %d",
error_prefix,
- size,
- array_max);
+ num,
+ array_num_max);
}
else {
PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected [%d - %d]",
+ "%.200s: sequence length is %d, expected [%d - %d]",
error_prefix,
- size,
- array_min,
- array_max);
+ num,
+ array_num_min,
+ array_num_max);
}
Py_DECREF(value_fast);
return -1;
}
- size = mathutils_array_parse_fast(array, size, value_fast, error_prefix);
+ num = mathutils_array_parse_fast(array, num, value_fast, error_prefix);
Py_DECREF(value_fast);
}
- if (size != -1) {
+ if (num != -1) {
if (flag & MU_ARRAY_ZERO) {
- const int size_left = array_max - size;
- if (size_left) {
- memset(&array[size], 0, sizeof(float) * size_left);
+ const int array_num_left = array_num_max - num;
+ if (array_num_left) {
+ memset(&array[num], 0, sizeof(float) * array_num_left);
}
}
}
- return size;
+ return num;
}
int mathutils_array_parse_alloc(float **array,
- int array_min,
+ int array_num,
PyObject *value,
const char *error_prefix)
{
- int size;
+ int num;
#if 1 /* approx 6x speedup for mathutils types */
- if ((size = VectorObject_Check(value) ? ((VectorObject *)value)->size : 0) ||
- (size = EulerObject_Check(value) ? 3 : 0) ||
- (size = QuaternionObject_Check(value) ? 4 : 0) ||
- (size = ColorObject_Check(value) ? 3 : 0)) {
+ if ((num = VectorObject_Check(value) ? ((VectorObject *)value)->vec_num : 0) ||
+ (num = EulerObject_Check(value) ? 3 : 0) || (num = QuaternionObject_Check(value) ? 4 : 0) ||
+ (num = ColorObject_Check(value) ? 3 : 0)) {
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- if (size < array_min) {
+ if (num < array_num) {
PyErr_Format(PyExc_ValueError,
"%.200s: sequence size is %d, expected > %d",
error_prefix,
- size,
- array_min);
+ num,
+ array_num);
return -1;
}
- *array = PyMem_Malloc(size * sizeof(float));
- memcpy(*array, ((const BaseMathObject *)value)->data, size * sizeof(float));
- return size;
+ *array = PyMem_Malloc(num * sizeof(float));
+ memcpy(*array, ((const BaseMathObject *)value)->data, num * sizeof(float));
+ return num;
}
#endif
@@ -230,21 +228,21 @@ int mathutils_array_parse_alloc(float **array,
return -1;
}
- size = PySequence_Fast_GET_SIZE(value_fast);
+ num = PySequence_Fast_GET_SIZE(value_fast);
- if (size < array_min) {
+ if (num < array_num) {
Py_DECREF(value_fast);
PyErr_Format(PyExc_ValueError,
"%.200s: sequence size is %d, expected > %d",
error_prefix,
- size,
- array_min);
+ num,
+ array_num);
return -1;
}
- *array = PyMem_Malloc(size * sizeof(float));
+ *array = PyMem_Malloc(num * sizeof(float));
- ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
+ ret = mathutils_array_parse_fast(*array, num, value_fast, error_prefix);
Py_DECREF(value_fast);
if (ret == -1) {
@@ -261,7 +259,7 @@ int mathutils_array_parse_alloc_v(float **array,
{
PyObject *value_fast;
const int array_dim_flag = array_dim;
- int i, size;
+ int i, num;
/* non list/tuple cases */
if (!(value_fast = PySequence_Fast(value, error_prefix))) {
@@ -269,30 +267,30 @@ int mathutils_array_parse_alloc_v(float **array,
return -1;
}
- size = PySequence_Fast_GET_SIZE(value_fast);
+ num = PySequence_Fast_GET_SIZE(value_fast);
- if (size != 0) {
+ if (num != 0) {
PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
float *fp;
array_dim &= ~MU_ARRAY_FLAGS;
- fp = *array = PyMem_Malloc(size * array_dim * sizeof(float));
+ fp = *array = PyMem_Malloc(num * array_dim * sizeof(float));
- for (i = 0; i < size; i++, fp += array_dim) {
+ for (i = 0; i < num; i++, fp += array_dim) {
PyObject *item = value_fast_items[i];
if (mathutils_array_parse(fp, array_dim, array_dim_flag, item, error_prefix) == -1) {
PyMem_Free(*array);
*array = NULL;
- size = -1;
+ num = -1;
break;
}
}
}
Py_DECREF(value_fast);
- return size;
+ return num;
}
int mathutils_int_array_parse(int *array, int array_dim, PyObject *value, const char *error_prefix)
@@ -458,7 +456,7 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
+ if (((MatrixObject *)value)->row_num < 3 || ((MatrixObject *)value)->col_num < 3) {
PyErr_Format(
PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
return -1;
diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h
index 5831489ef5b..84386e99d18 100644
--- a/source/blender/python/mathutils/mathutils.h
+++ b/source/blender/python/mathutils/mathutils.h
@@ -153,12 +153,12 @@ void _BaseMathObject_RaiseNotFrozenExc(const BaseMathObject *self);
* \return length of `value`, -1 on error.
*/
int mathutils_array_parse(
- float *array, int array_min, int array_max, PyObject *value, const char *error_prefix);
+ float *array, int array_num_min, int array_num_max, PyObject *value, const char *error_prefix);
/**
* \return -1 is returned on error and no allocation is made.
*/
int mathutils_array_parse_alloc(float **array,
- int array_min,
+ int array_num_min,
PyObject *value,
const char *error_prefix);
/**
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index b8eaf1486ab..76b5424711f 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -34,7 +34,7 @@ static PyObject *MatrixAccess_CreatePyObject(MatrixObject *matrix, const eMatrix
static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row)
{
- if ((vec->size != mat->num_col) || (row >= mat->num_row)) {
+ if ((vec->vec_num != mat->col_num) || (row >= mat->row_num)) {
PyErr_SetString(PyExc_AttributeError,
"Matrix(): "
"owner matrix has been resized since this row vector was created");
@@ -46,7 +46,7 @@ static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row
static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col)
{
- if ((vec->size != mat->num_row) || (col >= mat->num_col)) {
+ if ((vec->vec_num != mat->row_num) || (col >= mat->col_num)) {
PyErr_SetString(PyExc_AttributeError,
"Matrix(): "
"owner matrix has been resized since this column vector was created");
@@ -80,7 +80,7 @@ static int mathutils_matrix_row_get(BaseMathObject *bmo, int row)
return -1;
}
- for (col = 0; col < self->num_col; col++) {
+ for (col = 0; col < self->col_num; col++) {
bmo->data[col] = MATRIX_ITEM(self, row, col);
}
@@ -99,7 +99,7 @@ static int mathutils_matrix_row_set(BaseMathObject *bmo, int row)
return -1;
}
- for (col = 0; col < self->num_col; col++) {
+ for (col = 0; col < self->col_num; col++) {
MATRIX_ITEM(self, row, col) = bmo->data[col];
}
@@ -162,7 +162,7 @@ static int mathutils_matrix_col_check(BaseMathObject *bmo)
static int mathutils_matrix_col_get(BaseMathObject *bmo, int col)
{
MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int num_row;
+ int row_num;
int row;
if (BaseMath_ReadCallback(self) == -1) {
@@ -172,10 +172,10 @@ static int mathutils_matrix_col_get(BaseMathObject *bmo, int col)
return -1;
}
- /* for 'translation' size will always be '3' even on 4x4 vec */
- num_row = min_ii(self->num_row, ((const VectorObject *)bmo)->size);
+ /* for 'translation' `vec_num` will always be '3' even on 4x4 vec */
+ row_num = min_ii(self->row_num, ((const VectorObject *)bmo)->vec_num);
- for (row = 0; row < num_row; row++) {
+ for (row = 0; row < row_num; row++) {
bmo->data[row] = MATRIX_ITEM(self, row, col);
}
@@ -185,7 +185,7 @@ static int mathutils_matrix_col_get(BaseMathObject *bmo, int col)
static int mathutils_matrix_col_set(BaseMathObject *bmo, int col)
{
MatrixObject *self = (MatrixObject *)bmo->cb_user;
- int num_row;
+ int row_num;
int row;
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
@@ -195,10 +195,10 @@ static int mathutils_matrix_col_set(BaseMathObject *bmo, int col)
return -1;
}
- /* for 'translation' size will always be '3' even on 4x4 vec */
- num_row = min_ii(self->num_row, ((const VectorObject *)bmo)->size);
+ /* for 'translation' `vec_num` will always be '3' even on 4x4 vec */
+ row_num = min_ii(self->row_num, ((const VectorObject *)bmo)->vec_num);
- for (row = 0; row < num_row; row++) {
+ for (row = 0; row < row_num; row++) {
MATRIX_ITEM(self, row, col) = bmo->data[row];
}
@@ -349,18 +349,18 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
/* Input is now as a sequence of rows so length of sequence
* is the number of rows */
/* -1 is an error, size checks will account for this */
- const ushort num_row = PySequence_Size(arg);
+ const ushort row_num = PySequence_Size(arg);
- if (num_row >= 2 && num_row <= 4) {
+ if (row_num >= 2 && row_num <= 4) {
PyObject *item = PySequence_GetItem(arg, 0);
/* Since each item is a row, number of items is the
* same as the number of columns */
- const ushort num_col = PySequence_Size(item);
+ const ushort col_num = PySequence_Size(item);
Py_XDECREF(item);
- if (num_col >= 2 && num_col <= 4) {
+ if (col_num >= 2 && col_num <= 4) {
/* Sane row & col size, new matrix and assign as slice. */
- PyObject *matrix = Matrix_CreatePyObject(NULL, num_col, num_row, type);
+ PyObject *matrix = Matrix_CreatePyObject(NULL, col_num, row_num, type);
if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
return matrix;
}
@@ -613,7 +613,7 @@ PyDoc_STRVAR(C_Matrix_Scale_doc,
static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
{
PyObject *vec = NULL;
- int vec_size;
+ int vec_num;
float tvec[3];
float factor;
int matSize;
@@ -646,12 +646,10 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
return NULL;
}
if (vec) {
- vec_size = (matSize == 2 ? 2 : 3);
- if (mathutils_array_parse(tvec,
- vec_size,
- vec_size,
- vec,
- "Matrix.Scale(factor, size, axis), invalid 'axis' arg") == -1) {
+ vec_num = (matSize == 2 ? 2 : 3);
+ if (mathutils_array_parse(
+ tvec, vec_num, vec_num, vec, "Matrix.Scale(factor, size, axis), invalid 'axis' arg") ==
+ -1) {
return NULL;
}
}
@@ -671,11 +669,11 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args)
* normalize arbitrary axis */
float norm = 0.0f;
int x;
- for (x = 0; x < vec_size; x++) {
+ for (x = 0; x < vec_num; x++) {
norm += tvec[x] * tvec[x];
}
norm = sqrtf(norm);
- for (x = 0; x < vec_size; x++) {
+ for (x = 0; x < vec_num; x++) {
tvec[x] /= norm;
}
if (matSize == 2) {
@@ -795,23 +793,23 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args)
else {
/* arbitrary plane */
- const int vec_size = (matSize == 2 ? 2 : 3);
+ const int vec_num = (matSize == 2 ? 2 : 3);
float tvec[4];
if (mathutils_array_parse(tvec,
- vec_size,
- vec_size,
+ vec_num,
+ vec_num,
axis,
"Matrix.OrthoProjection(axis, size), invalid 'axis' arg") == -1) {
return NULL;
}
/* normalize arbitrary axis */
- for (x = 0; x < vec_size; x++) {
+ for (x = 0; x < vec_num; x++) {
norm += tvec[x] * tvec[x];
}
norm = sqrtf(norm);
- for (x = 0; x < vec_size; x++) {
+ for (x = 0; x < vec_num; x++) {
tvec[x] /= norm;
}
if (matSize == 2) {
@@ -1019,7 +1017,7 @@ static PyObject *C_Matrix_LocRotScale(PyObject *cls, PyObject *args)
return NULL;
}
- if (mat_obj->num_col == 3 && mat_obj->num_row == 3) {
+ if (mat_obj->col_num == 3 && mat_obj->row_num == 3) {
copy_m4_m3(mat, (const float(*)[3])mat_obj->matrix);
}
else {
@@ -1062,20 +1060,20 @@ void matrix_as_3x3(float mat[3][3], MatrixObject *self)
static void matrix_copy(MatrixObject *mat_dst, const MatrixObject *mat_src)
{
- BLI_assert((mat_dst->num_col == mat_src->num_col) && (mat_dst->num_row == mat_src->num_row));
+ BLI_assert((mat_dst->col_num == mat_src->col_num) && (mat_dst->row_num == mat_src->row_num));
BLI_assert(mat_dst != mat_src);
- memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->num_col * mat_dst->num_row));
+ memcpy(mat_dst->matrix, mat_src->matrix, sizeof(float) * (mat_dst->col_num * mat_dst->row_num));
}
static void matrix_unit_internal(MatrixObject *self)
{
- const int mat_size = sizeof(float) * (self->num_col * self->num_row);
+ const int mat_size = sizeof(float) * (self->col_num * self->row_num);
memset(self->matrix, 0x0, mat_size);
- const int col_row_max = min_ii(self->num_col, self->num_row);
- const int num_row = self->num_row;
+ const int col_row_max = min_ii(self->col_num, self->row_num);
+ const int row_num = self->row_num;
for (int col = 0; col < col_row_max; col++) {
- self->matrix[(col * num_row) + col] = 1.0f;
+ self->matrix[(col * row_num) + col] = 1.0f;
}
}
@@ -1085,8 +1083,8 @@ static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *ma
ushort col, row;
uint i = 0;
- for (row = 0; row < mat_src->num_row; row++) {
- for (col = 0; col < mat_src->num_col; col++) {
+ for (row = 0; row < mat_src->row_num; row++) {
+ for (col = 0; col < mat_src->col_num; col++) {
mat_dst_fl[i++] = MATRIX_ITEM(mat_src, row, col);
}
}
@@ -1095,13 +1093,13 @@ static void matrix_transpose_internal(float mat_dst_fl[], const MatrixObject *ma
/* assumes rowsize == colsize is checked and the read callback has run */
static float matrix_determinant_internal(const MatrixObject *self)
{
- if (self->num_col == 2) {
+ if (self->col_num == 2) {
return determinant_m2(MATRIX_ITEM(self, 0, 0),
MATRIX_ITEM(self, 0, 1),
MATRIX_ITEM(self, 1, 0),
MATRIX_ITEM(self, 1, 1));
}
- if (self->num_col == 3) {
+ if (self->col_num == 3) {
return determinant_m3(MATRIX_ITEM(self, 0, 0),
MATRIX_ITEM(self, 0, 1),
MATRIX_ITEM(self, 0, 2),
@@ -1152,8 +1150,8 @@ static void matrix_invert_with_det_n_internal(float *mat_dst,
/* divide by determinant & set values */
k = 0;
- for (i = 0; i < dim; i++) { /* num_col */
- for (j = 0; j < dim; j++) { /* num_row */
+ for (i = 0; i < dim; i++) { /* col_num */
+ for (j = 0; j < dim; j++) { /* row_num */
mat_dst[MATRIX_ITEM_INDEX_NUMROW(dim, j, i)] = mat[k++] / det;
}
}
@@ -1165,11 +1163,11 @@ static void matrix_invert_with_det_n_internal(float *mat_dst,
static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
{
float det;
- BLI_assert(self->num_col == self->num_row);
+ BLI_assert(self->col_num == self->row_num);
det = matrix_determinant_internal(self);
if (det != 0.0f) {
- matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col);
+ matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->col_num);
return true;
}
@@ -1184,7 +1182,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
{
float det;
float *in_mat = self->matrix;
- BLI_assert(self->num_col == self->num_row);
+ BLI_assert(self->col_num == self->row_num);
det = matrix_determinant_internal(self);
if (det == 0.0f) {
@@ -1194,7 +1192,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
* and modify it in place to add diagonal epsilon. */
in_mat = r_mat;
- switch (self->num_col) {
+ switch (self->col_num) {
case 2: {
float(*mat)[2] = (float(*)[2])in_mat;
@@ -1248,7 +1246,7 @@ static void matrix_invert_safe_internal(const MatrixObject *self, float *r_mat)
}
}
- matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->num_col);
+ matrix_invert_with_det_n_internal(r_mat, in_mat, det, self->col_num);
}
/*-----------------------------METHODS----------------------------*/
@@ -1268,13 +1266,13 @@ static PyObject *Matrix_to_quaternion(MatrixObject *self)
}
/* must be 3-4 cols, 3-4 rows, square matrix */
- if ((self->num_row < 3) || (self->num_col < 3) || (self->num_row != self->num_col)) {
+ if ((self->row_num < 3) || (self->col_num < 3) || (self->row_num != self->col_num)) {
PyErr_SetString(PyExc_ValueError,
"Matrix.to_quat(): "
"inappropriate matrix size - expects 3x3 or 4x4 matrix");
return NULL;
}
- if (self->num_row == 3) {
+ if (self->row_num == 3) {
mat3_to_quat(quat, (float(*)[3])self->matrix);
}
else {
@@ -1326,10 +1324,10 @@ static PyObject *Matrix_to_euler(MatrixObject *self, PyObject *args)
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if (self->num_row == 3 && self->num_col == 3) {
+ if (self->row_num == 3 && self->col_num == 3) {
copy_m3_m3(mat, (const float(*)[3])self->matrix);
}
- else if (self->num_row == 4 && self->num_col == 4) {
+ else if (self->row_num == 4 && self->col_num == 4) {
copy_m3_m4(mat, (const float(*)[4])self->matrix);
}
else {
@@ -1401,36 +1399,36 @@ static PyObject *Matrix_resize_4x4(MatrixObject *self)
unit_m4(mat);
- for (col = 0; col < self->num_col; col++) {
- memcpy(mat[col], MATRIX_COL_PTR(self, col), self->num_row * sizeof(float));
+ for (col = 0; col < self->col_num; col++) {
+ memcpy(mat[col], MATRIX_COL_PTR(self, col), self->row_num * sizeof(float));
}
copy_m4_m4((float(*)[4])self->matrix, (const float(*)[4])mat);
- self->num_col = 4;
- self->num_row = 4;
+ self->col_num = 4;
+ self->row_num = 4;
Py_RETURN_NONE;
}
-static PyObject *Matrix_to_NxN(MatrixObject *self, const int num_col, const int num_row)
+static PyObject *Matrix_to_NxN(MatrixObject *self, const int col_num, const int row_num)
{
- const int mat_size = sizeof(float) * (num_col * num_row);
+ const int mat_size = sizeof(float) * (col_num * row_num);
MatrixObject *pymat = (MatrixObject *)Matrix_CreatePyObject_alloc(
- PyMem_Malloc(mat_size), num_col, num_row, Py_TYPE(self));
+ PyMem_Malloc(mat_size), col_num, row_num, Py_TYPE(self));
- if ((self->num_row == num_row) && (self->num_col == num_col)) {
+ if ((self->row_num == row_num) && (self->col_num == col_num)) {
memcpy(pymat->matrix, self->matrix, mat_size);
}
else {
- if ((self->num_col < num_col) || (self->num_row < num_row)) {
+ if ((self->col_num < col_num) || (self->row_num < row_num)) {
matrix_unit_internal(pymat);
}
- const int col_len_src = min_ii(num_col, self->num_col);
- const int row_len_src = min_ii(num_row, self->num_row);
+ const int col_len_src = min_ii(col_num, self->col_num);
+ const int row_len_src = min_ii(row_num, self->row_num);
for (int col = 0; col < col_len_src; col++) {
memcpy(
- &pymat->matrix[col * num_row], MATRIX_COL_PTR(self, col), sizeof(float) * row_len_src);
+ &pymat->matrix[col * row_num], MATRIX_COL_PTR(self, col), sizeof(float) * row_len_src);
}
}
return (PyObject *)pymat;
@@ -1495,7 +1493,7 @@ static PyObject *Matrix_to_translation(MatrixObject *self)
return NULL;
}
- if ((self->num_row < 3) || self->num_col < 4) {
+ if ((self->row_num < 3) || self->col_num < 4) {
PyErr_SetString(PyExc_ValueError,
"Matrix.to_translation(): "
"inappropriate matrix size");
@@ -1526,7 +1524,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if ((self->num_row < 3) || (self->num_col < 3)) {
+ if ((self->row_num < 3) || (self->col_num < 3)) {
PyErr_SetString(PyExc_ValueError,
"Matrix.to_scale(): "
"inappropriate matrix size, 3x3 minimum size");
@@ -1546,7 +1544,7 @@ static PyObject *Matrix_to_scale(MatrixObject *self)
/* re-usable checks for invert */
static bool matrix_invert_is_compat(const MatrixObject *self)
{
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.invert(ed): "
"only square matrices are supported");
@@ -1571,7 +1569,7 @@ static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, b
return false;
}
- if ((self->num_col != fallback->num_col) || (self->num_row != fallback->num_row)) {
+ if ((self->col_num != fallback->col_num) || (self->row_num != fallback->row_num)) {
PyErr_SetString(PyExc_TypeError,
"Matrix.invert: "
"matrix argument has different dimensions");
@@ -1782,7 +1780,7 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
return NULL;
}
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.adjugate(d): "
"only square matrices are supported");
@@ -1790,12 +1788,12 @@ static PyObject *Matrix_adjugate(MatrixObject *self)
}
/* calculate the classical adjoint */
- if (self->num_col <= 4) {
- adjoint_matrix_n(self->matrix, self->matrix, self->num_col);
+ if (self->col_num <= 4) {
+ adjoint_matrix_n(self->matrix, self->matrix, self->col_num);
}
else {
PyErr_Format(
- PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->num_col);
+ PyExc_ValueError, "Matrix adjugate(d): size (%d) unsupported", (int)self->col_num);
return NULL;
}
@@ -1838,7 +1836,7 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
return NULL;
}
- if (self->num_row != 3 || self->num_col != 3) {
+ if (self->row_num != 3 || self->col_num != 3) {
PyErr_SetString(PyExc_ValueError,
"Matrix.rotate(): "
"must have 3x3 dimensions");
@@ -1870,7 +1868,7 @@ static PyObject *Matrix_decompose(MatrixObject *self)
float quat[4];
float size[3];
- if (self->num_row != 4 || self->num_col != 4) {
+ if (self->row_num != 4 || self->col_num != 4) {
PyErr_SetString(PyExc_ValueError,
"Matrix.decompose(): "
"inappropriate matrix size - expects 4x4 matrix");
@@ -1913,7 +1911,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
- if (self->num_col != mat2->num_col || self->num_row != mat2->num_row) {
+ if (self->col_num != mat2->col_num || self->row_num != mat2->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.lerp(): "
"expects both matrix objects of the same dimensions");
@@ -1925,14 +1923,14 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
}
/* TODO: different sized matrix. */
- if (self->num_col == 4 && self->num_row == 4) {
+ if (self->col_num == 4 && self->row_num == 4) {
#ifdef MATH_STANDALONE
blend_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac);
#else
interp_m4_m4m4((float(*)[4])mat, (float(*)[4])self->matrix, (float(*)[4])mat2->matrix, fac);
#endif
}
- else if (self->num_col == 3 && self->num_row == 3) {
+ else if (self->col_num == 3 && self->row_num == 3) {
#ifdef MATH_STANDALONE
blend_m3_m3m3((float(*)[3])mat, (float(*)[3])self->matrix, (float(*)[3])mat2->matrix, fac);
#else
@@ -1946,7 +1944,7 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
return NULL;
}
- return Matrix_CreatePyObject(mat, self->num_col, self->num_row, Py_TYPE(self));
+ return Matrix_CreatePyObject(mat, self->col_num, self->row_num, Py_TYPE(self));
}
/*---------------------------matrix.determinant() ----------------*/
@@ -1966,7 +1964,7 @@ static PyObject *Matrix_determinant(MatrixObject *self)
return NULL;
}
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.determinant(): "
"only square matrices are supported");
@@ -1989,19 +1987,19 @@ static PyObject *Matrix_transpose(MatrixObject *self)
return NULL;
}
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.transpose(d): "
"only square matrices are supported");
return NULL;
}
- if (self->num_col == 2) {
+ if (self->col_num == 2) {
const float t = MATRIX_ITEM(self, 1, 0);
MATRIX_ITEM(self, 1, 0) = MATRIX_ITEM(self, 0, 1);
MATRIX_ITEM(self, 0, 1) = t;
}
- else if (self->num_col == 3) {
+ else if (self->col_num == 3) {
transpose_m3((float(*)[3])self->matrix);
}
else {
@@ -2035,17 +2033,17 @@ static PyObject *Matrix_normalize(MatrixObject *self)
return NULL;
}
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.normalize(): "
"only square matrices are supported");
return NULL;
}
- if (self->num_col == 3) {
+ if (self->col_num == 3) {
normalize_m3((float(*)[3])self->matrix);
}
- else if (self->num_col == 4) {
+ else if (self->col_num == 4) {
normalize_m4((float(*)[4])self->matrix);
}
else {
@@ -2083,7 +2081,7 @@ static PyObject *Matrix_zero(MatrixObject *self)
return NULL;
}
- copy_vn_fl(self->matrix, self->num_col * self->num_row, 0.0f);
+ copy_vn_fl(self->matrix, self->col_num * self->row_num, 0.0f);
if (BaseMath_WriteCallback(self) == -1) {
return NULL;
@@ -2094,12 +2092,12 @@ static PyObject *Matrix_zero(MatrixObject *self)
/*---------------------------matrix.identity(() ------------------*/
static void matrix_identity_internal(MatrixObject *self)
{
- BLI_assert((self->num_col == self->num_row) && (self->num_row <= 4));
+ BLI_assert((self->col_num == self->row_num) && (self->row_num <= 4));
- if (self->num_col == 2) {
+ if (self->col_num == 2) {
unit_m2((float(*)[2])self->matrix);
}
- else if (self->num_col == 3) {
+ else if (self->col_num == 3) {
unit_m3((float(*)[3])self->matrix);
}
else {
@@ -2123,7 +2121,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
return NULL;
}
- if (self->num_col != self->num_row) {
+ if (self->col_num != self->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix.identity(): "
"only square matrices are supported");
@@ -2143,7 +2141,7 @@ static PyObject *Matrix_identity(MatrixObject *self)
static PyObject *Matrix_copy_notest(MatrixObject *self, const float *matrix)
{
- return Matrix_CreatePyObject((const float *)matrix, self->num_col, self->num_row, Py_TYPE(self));
+ return Matrix_CreatePyObject((const float *)matrix, self->col_num, self->row_num, Py_TYPE(self));
}
PyDoc_STRVAR(Matrix_copy_doc,
@@ -2180,13 +2178,13 @@ static PyObject *Matrix_repr(MatrixObject *self)
return NULL;
}
- for (row = 0; row < self->num_row; row++) {
- rows[row] = PyTuple_New(self->num_col);
- for (col = 0; col < self->num_col; col++) {
+ for (row = 0; row < self->row_num; row++) {
+ rows[row] = PyTuple_New(self->col_num);
+ for (col = 0; col < self->col_num; col++) {
PyTuple_SET_ITEM(rows[row], col, PyFloat_FromDouble(MATRIX_ITEM(self, row, col)));
}
}
- switch (self->num_row) {
+ switch (self->row_num) {
case 2:
return PyUnicode_FromFormat(
"Matrix((%R,\n"
@@ -2236,9 +2234,9 @@ static PyObject *Matrix_str(MatrixObject *self)
ds = BLI_dynstr_new();
/* First determine the maximum width for each column */
- for (col = 0; col < self->num_col; col++) {
+ for (col = 0; col < self->col_num; col++) {
maxsize[col] = 0;
- for (row = 0; row < self->num_row; row++) {
+ for (row = 0; row < self->row_num; row++) {
const int size = BLI_snprintf_rlen(
dummy_buf, sizeof(dummy_buf), "%.4f", MATRIX_ITEM(self, row, col));
maxsize[col] = max_ii(maxsize[col], size);
@@ -2246,12 +2244,12 @@ static PyObject *Matrix_str(MatrixObject *self)
}
/* Now write the unicode string to be printed */
- BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->num_row, self->num_col);
- for (row = 0; row < self->num_row; row++) {
- for (col = 0; col < self->num_col; col++) {
+ BLI_dynstr_appendf(ds, "<Matrix %dx%d (", self->row_num, self->col_num);
+ for (row = 0; row < self->row_num; row++) {
+ for (col = 0; col < self->col_num; col++) {
BLI_dynstr_appendf(ds, col ? ", %*.4f" : "%*.4f", maxsize[col], MATRIX_ITEM(self, row, col));
}
- BLI_dynstr_append(ds, row + 1 != self->num_row ? ")\n (" : ")");
+ BLI_dynstr_append(ds, row + 1 != self->row_num ? ")\n (" : ")");
}
BLI_dynstr_append(ds, ">");
@@ -2272,8 +2270,8 @@ static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
return NULL;
}
- ok = ((matA->num_row == matB->num_row) && (matA->num_col == matB->num_col) &&
- EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->num_col * matA->num_row), 1)) ?
+ ok = ((matA->row_num == matB->row_num) && (matA->col_num == matB->col_num) &&
+ EXPP_VectorsAreEqual(matA->matrix, matB->matrix, (matA->col_num * matA->row_num), 1)) ?
0 :
-1;
}
@@ -2314,7 +2312,7 @@ static Py_hash_t Matrix_hash(MatrixObject *self)
matrix_transpose_internal(mat, self);
- return mathutils_array_hash(mat, self->num_row * self->num_col);
+ return mathutils_array_hash(mat, self->row_num * self->col_num);
}
/*---------------------SEQUENCE PROTOCOLS------------------------
@@ -2322,7 +2320,7 @@ static Py_hash_t Matrix_hash(MatrixObject *self)
* sequence length */
static int Matrix_len(MatrixObject *self)
{
- return self->num_row;
+ return self->row_num;
}
/*----------------------------object[]---------------------------
* sequence accessor (get)
@@ -2333,14 +2331,14 @@ static PyObject *Matrix_item_row(MatrixObject *self, int row)
return NULL;
}
- if (row < 0 || row >= self->num_row) {
+ if (row < 0 || row >= self->row_num) {
PyErr_SetString(PyExc_IndexError,
"matrix[attribute]: "
"array index out of range");
return NULL;
}
return Vector_CreatePyObject_cb(
- (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, row);
+ (PyObject *)self, self->col_num, mathutils_matrix_row_cb_index, row);
}
/* same but column access */
static PyObject *Matrix_item_col(MatrixObject *self, int col)
@@ -2349,14 +2347,14 @@ static PyObject *Matrix_item_col(MatrixObject *self, int col)
return NULL;
}
- if (col < 0 || col >= self->num_col) {
+ if (col < 0 || col >= self->col_num) {
PyErr_SetString(PyExc_IndexError,
"matrix[attribute]: "
"array index out of range");
return NULL;
}
return Vector_CreatePyObject_cb(
- (PyObject *)self, self->num_row, mathutils_matrix_col_cb_index, col);
+ (PyObject *)self, self->row_num, mathutils_matrix_col_cb_index, col);
}
/*----------------------------object[]-------------------------
@@ -2370,18 +2368,18 @@ static int Matrix_ass_item_row(MatrixObject *self, int row, PyObject *value)
return -1;
}
- if (row >= self->num_row || row < 0) {
+ if (row >= self->row_num || row < 0) {
PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad row");
return -1;
}
if (mathutils_array_parse(
- vec, self->num_col, self->num_col, value, "matrix[i] = value assignment") == -1) {
+ vec, self->col_num, self->col_num, value, "matrix[i] = value assignment") == -1) {
return -1;
}
/* Since we are assigning a row we cannot memcpy */
- for (col = 0; col < self->num_col; col++) {
+ for (col = 0; col < self->col_num; col++) {
MATRIX_ITEM(self, row, col) = vec[col];
}
@@ -2396,18 +2394,18 @@ static int Matrix_ass_item_col(MatrixObject *self, int col, PyObject *value)
return -1;
}
- if (col >= self->num_col || col < 0) {
+ if (col >= self->col_num || col < 0) {
PyErr_SetString(PyExc_IndexError, "matrix[attribute] = x: bad col");
return -1;
}
if (mathutils_array_parse(
- vec, self->num_row, self->num_row, value, "matrix[i] = value assignment") == -1) {
+ vec, self->row_num, self->row_num, value, "matrix[i] = value assignment") == -1) {
return -1;
}
/* Since we are assigning a row we cannot memcpy */
- for (row = 0; row < self->num_row; row++) {
+ for (row = 0; row < self->row_num; row++) {
MATRIX_ITEM(self, row, col) = vec[row];
}
@@ -2427,8 +2425,8 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
return NULL;
}
- CLAMP(begin, 0, self->num_row);
- CLAMP(end, 0, self->num_row);
+ CLAMP(begin, 0, self->row_num);
+ CLAMP(end, 0, self->row_num);
begin = MIN2(begin, end);
tuple = PyTuple_New(end - begin);
@@ -2436,7 +2434,7 @@ static PyObject *Matrix_slice(MatrixObject *self, int begin, int end)
PyTuple_SET_ITEM(tuple,
count - begin,
Vector_CreatePyObject_cb(
- (PyObject *)self, self->num_col, mathutils_matrix_row_cb_index, count));
+ (PyObject *)self, self->col_num, mathutils_matrix_row_cb_index, count));
}
return tuple;
@@ -2451,8 +2449,8 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
return -1;
}
- CLAMP(begin, 0, self->num_row);
- CLAMP(end, 0, self->num_row);
+ CLAMP(begin, 0, self->row_num);
+ CLAMP(end, 0, self->row_num);
begin = MIN2(begin, end);
/* non list/tuple cases */
@@ -2475,7 +2473,7 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
return -1;
}
- memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float));
+ memcpy(mat, self->matrix, self->col_num * self->row_num * sizeof(float));
/* parse sub items */
for (row = begin; row < end; row++) {
@@ -2483,21 +2481,21 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
PyObject *item = value_fast_items[row - begin];
if (mathutils_array_parse(
- vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") ==
+ vec, self->col_num, self->col_num, item, "matrix[begin:end] = value assignment") ==
-1) {
Py_DECREF(value_fast);
return -1;
}
- for (col = 0; col < self->num_col; col++) {
- mat[col * self->num_row + row] = vec[col];
+ for (col = 0; col < self->col_num; col++) {
+ mat[col * self->row_num + row] = vec[col];
}
}
Py_DECREF(value_fast);
/* Parsed well - now set in matrix. */
- memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float));
+ memcpy(self->matrix, mat, self->col_num * self->row_num * sizeof(float));
(void)BaseMath_WriteCallback(self);
return 0;
@@ -2525,16 +2523,16 @@ static PyObject *Matrix_add(PyObject *m1, PyObject *m2)
return NULL;
}
- if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
+ if (mat1->col_num != mat2->col_num || mat1->row_num != mat2->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
}
- add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ add_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1));
}
/*------------------------obj - obj------------------------------
* subtraction */
@@ -2559,24 +2557,24 @@ static PyObject *Matrix_sub(PyObject *m1, PyObject *m2)
return NULL;
}
- if (mat1->num_col != mat2->num_col || mat1->num_row != mat2->num_row) {
+ if (mat1->col_num != mat2->col_num || mat1->row_num != mat2->row_num) {
PyErr_SetString(PyExc_ValueError,
"Matrix addition: "
"matrices must have the same dimensions for this operation");
return NULL;
}
- sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ sub_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num);
- return Matrix_CreatePyObject(mat, mat1->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat1->col_num, mat1->row_num, Py_TYPE(mat1));
}
/*------------------------obj * obj------------------------------
* element-wise multiplication */
static PyObject *matrix_mul_float(MatrixObject *mat, const float scalar)
{
float tmat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- mul_vn_vn_fl(tmat, mat->matrix, mat->num_col * mat->num_row, scalar);
- return Matrix_CreatePyObject(tmat, mat->num_col, mat->num_row, Py_TYPE(mat));
+ mul_vn_vn_fl(tmat, mat->matrix, mat->col_num * mat->row_num, scalar);
+ return Matrix_CreatePyObject(tmat, mat->col_num, mat->row_num, Py_TYPE(mat));
}
static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
@@ -2602,16 +2600,16 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
/* MATRIX * MATRIX */
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
+ if ((mat1->row_num != mat2->row_num) || (mat1->col_num != mat2->col_num)) {
PyErr_SetString(PyExc_ValueError,
"matrix1 * matrix2: matrix1 number of rows/columns "
"and the matrix2 number of rows/columns must be the same");
return NULL;
}
- mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ mul_vn_vnvn(mat, mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num);
- return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat2->col_num, mat1->row_num, Py_TYPE(mat1));
}
if (mat2) {
/* FLOAT/INT * MATRIX */
@@ -2656,18 +2654,18 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
if (mat1 && mat2) {
/* MATRIX *= MATRIX */
- if ((mat1->num_row != mat2->num_row) || (mat1->num_col != mat2->num_col)) {
+ if ((mat1->row_num != mat2->row_num) || (mat1->col_num != mat2->col_num)) {
PyErr_SetString(PyExc_ValueError,
"matrix1 *= matrix2: matrix1 number of rows/columns "
"and the matrix2 number of rows/columns must be the same");
return NULL;
}
- mul_vn_vn(mat1->matrix, mat2->matrix, mat1->num_col * mat1->num_row);
+ mul_vn_vn(mat1->matrix, mat2->matrix, mat1->col_num * mat1->row_num);
}
else if (mat1 && (((scalar = PyFloat_AsDouble(m2)) == -1.0f && PyErr_Occurred()) == 0)) {
/* MATRIX *= FLOAT/INT */
- mul_vn_fl(mat1->matrix, mat1->num_row * mat1->num_col, scalar);
+ mul_vn_fl(mat1->matrix, mat1->row_num * mat1->col_num, scalar);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2686,7 +2684,7 @@ static PyObject *Matrix_imul(PyObject *m1, PyObject *m2)
* matrix multiplication */
static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
{
- int vec_size;
+ int vec_num;
MatrixObject *mat1 = NULL, *mat2 = NULL;
@@ -2709,24 +2707,24 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
int col, row, item;
- if (mat1->num_col != mat2->num_row) {
+ if (mat1->col_num != mat2->row_num) {
PyErr_SetString(PyExc_ValueError,
"matrix1 * matrix2: matrix1 number of columns "
"and the matrix2 number of rows must be the same");
return NULL;
}
- for (col = 0; col < mat2->num_col; col++) {
- for (row = 0; row < mat1->num_row; row++) {
+ for (col = 0; col < mat2->col_num; col++) {
+ for (row = 0; row < mat1->row_num; row++) {
double dot = 0.0f;
- for (item = 0; item < mat1->num_col; item++) {
+ for (item = 0; item < mat1->col_num; item++) {
dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
}
- mat[(col * mat1->num_row) + row] = (float)dot;
+ mat[(col * mat1->row_num) + row] = (float)dot;
}
}
- return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
+ return Matrix_CreatePyObject(mat, mat2->col_num, mat1->row_num, Py_TYPE(mat1));
}
if (mat1) {
/* MATRIX @ VECTOR */
@@ -2740,14 +2738,14 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
return NULL;
}
- if (mat1->num_col == 4 && vec2->size == 3) {
- vec_size = 3;
+ if (mat1->col_num == 4 && vec2->vec_num == 3) {
+ vec_num = 3;
}
else {
- vec_size = mat1->num_row;
+ vec_num = mat1->row_num;
}
- return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(m2));
+ return Vector_CreatePyObject(tvec, vec_num, Py_TYPE(m2));
}
}
@@ -2782,27 +2780,27 @@ static PyObject *Matrix_imatmul(PyObject *m1, PyObject *m2)
float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
int col, row, item;
- if (mat1->num_col != mat2->num_row) {
+ if (mat1->col_num != mat2->row_num) {
PyErr_SetString(PyExc_ValueError,
"matrix1 * matrix2: matrix1 number of columns "
"and the matrix2 number of rows must be the same");
return NULL;
}
- for (col = 0; col < mat2->num_col; col++) {
- for (row = 0; row < mat1->num_row; row++) {
+ for (col = 0; col < mat2->col_num; col++) {
+ for (row = 0; row < mat1->row_num; row++) {
double dot = 0.0f;
- for (item = 0; item < mat1->num_col; item++) {
+ for (item = 0; item < mat1->col_num; item++) {
dot += (double)(MATRIX_ITEM(mat1, row, item) * MATRIX_ITEM(mat2, item, col));
}
/* store in new matrix as overwriting original at this point will cause
* subsequent iterations to use incorrect values */
- mat[(col * mat1->num_row) + row] = (float)dot;
+ mat[(col * mat1->row_num) + row] = (float)dot;
}
}
/* copy matrix back */
- memcpy(mat1->matrix, mat, (mat1->num_row * mat1->num_col) * sizeof(float));
+ memcpy(mat1->matrix, mat, (mat1->row_num * mat1->col_num) * sizeof(float));
}
else {
PyErr_Format(PyExc_TypeError,
@@ -2841,14 +2839,14 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item)
return NULL;
}
if (i < 0) {
- i += self->num_row;
+ i += self->row_num;
}
return Matrix_item_row(self, i);
}
if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
+ if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
return NULL;
}
@@ -2876,14 +2874,14 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va
return -1;
}
if (i < 0) {
- i += self->num_row;
+ i += self->row_num;
}
return Matrix_ass_item_row(self, i, value);
}
if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
+ if (PySlice_GetIndicesEx(item, self->row_num, &start, &stop, &step, &slicelength) < 0) {
return -1;
}
@@ -2955,7 +2953,7 @@ static PyObject *Matrix_translation_get(MatrixObject *self, void *UNUSED(closure
}
/* Must be 4x4 square matrix. */
- if (self->num_row != 4 || self->num_col != 4) {
+ if (self->row_num != 4 || self->col_num != 4) {
PyErr_SetString(PyExc_AttributeError,
"Matrix.translation: "
"inappropriate matrix size, must be 4x4");
@@ -2977,7 +2975,7 @@ static int Matrix_translation_set(MatrixObject *self, PyObject *value, void *UNU
}
/* Must be 4x4 square matrix. */
- if (self->num_row != 4 || self->num_col != 4) {
+ if (self->row_num != 4 || self->col_num != 4) {
PyErr_SetString(PyExc_AttributeError,
"Matrix.translation: "
"inappropriate matrix size, must be 4x4");
@@ -3021,7 +3019,7 @@ static PyObject *Matrix_median_scale_get(MatrixObject *self, void *UNUSED(closur
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if ((self->num_row < 3) || (self->num_col < 3)) {
+ if ((self->row_num < 3) || (self->col_num < 3)) {
PyErr_SetString(PyExc_AttributeError,
"Matrix.median_scale: "
"inappropriate matrix size, 3x3 minimum");
@@ -3043,10 +3041,10 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if (self->num_row == 4 && self->num_col == 4) {
+ if (self->row_num == 4 && self->col_num == 4) {
return PyBool_FromLong(is_negative_m4((const float(*)[4])self->matrix));
}
- if (self->num_row == 3 && self->num_col == 3) {
+ if (self->row_num == 3 && self->col_num == 3) {
return PyBool_FromLong(is_negative_m3((const float(*)[3])self->matrix));
}
@@ -3065,10 +3063,10 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if (self->num_row == 4 && self->num_col == 4) {
+ if (self->row_num == 4 && self->col_num == 4) {
return PyBool_FromLong(is_orthonormal_m4((const float(*)[4])self->matrix));
}
- if (self->num_row == 3 && self->num_col == 3) {
+ if (self->row_num == 3 && self->col_num == 3) {
return PyBool_FromLong(is_orthonormal_m3((const float(*)[3])self->matrix));
}
@@ -3088,10 +3086,10 @@ static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void
}
/* Must be 3-4 cols, 3-4 rows, square matrix. */
- if (self->num_row == 4 && self->num_col == 4) {
+ if (self->row_num == 4 && self->col_num == 4) {
return PyBool_FromLong(is_orthogonal_m4((const float(*)[4])self->matrix));
}
- if (self->num_row == 3 && self->num_col == 3) {
+ if (self->row_num == 3 && self->col_num == 3) {
return PyBool_FromLong(is_orthogonal_m3((const float(*)[3])self->matrix));
}
@@ -3271,22 +3269,22 @@ PyTypeObject matrix_Type = {
};
PyObject *Matrix_CreatePyObject(const float *mat,
- const ushort num_col,
- const ushort num_row,
+ const ushort col_num,
+ const ushort row_num,
PyTypeObject *base_type)
{
MatrixObject *self;
float *mat_alloc;
/* matrix objects can be any 2-4row x 2-4col matrix */
- if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
+ if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) {
PyErr_SetString(PyExc_RuntimeError,
"Matrix(): "
"row and column sizes must be between 2 and 4");
return NULL;
}
- mat_alloc = PyMem_Malloc(num_col * num_row * sizeof(float));
+ mat_alloc = PyMem_Malloc(col_num * row_num * sizeof(float));
if (UNLIKELY(mat_alloc == NULL)) {
PyErr_SetString(PyExc_MemoryError,
"Matrix(): "
@@ -3297,23 +3295,23 @@ PyObject *Matrix_CreatePyObject(const float *mat,
self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
if (self) {
self->matrix = mat_alloc;
- self->num_col = num_col;
- self->num_row = num_row;
+ self->col_num = col_num;
+ self->row_num = row_num;
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
if (mat) { /* If a float array passed. */
- memcpy(self->matrix, mat, num_col * num_row * sizeof(float));
+ memcpy(self->matrix, mat, col_num * row_num * sizeof(float));
}
- else if (num_col == num_row) {
+ else if (col_num == row_num) {
/* or if no arguments are passed return identity matrix for square matrices */
matrix_identity_internal(self);
}
else {
/* otherwise zero everything */
- memset(self->matrix, 0, num_col * num_row * sizeof(float));
+ memset(self->matrix, 0, col_num * row_num * sizeof(float));
}
self->flag = BASE_MATH_FLAG_DEFAULT;
}
@@ -3325,14 +3323,14 @@ PyObject *Matrix_CreatePyObject(const float *mat,
}
PyObject *Matrix_CreatePyObject_wrap(float *mat,
- const ushort num_col,
- const ushort num_row,
+ const ushort col_num,
+ const ushort row_num,
PyTypeObject *base_type)
{
MatrixObject *self;
/* matrix objects can be any 2-4row x 2-4col matrix */
- if (num_col < 2 || num_col > 4 || num_row < 2 || num_row > 4) {
+ if (col_num < 2 || col_num > 4 || row_num < 2 || row_num > 4) {
PyErr_SetString(PyExc_RuntimeError,
"Matrix(): "
"row and column sizes must be between 2 and 4");
@@ -3341,8 +3339,8 @@ PyObject *Matrix_CreatePyObject_wrap(float *mat,
self = BASE_MATH_NEW(MatrixObject, matrix_Type, base_type);
if (self) {
- self->num_col = num_col;
- self->num_row = num_row;
+ self->col_num = col_num;
+ self->row_num = row_num;
/* init callbacks as NULL */
self->cb_user = NULL;
@@ -3355,9 +3353,9 @@ PyObject *Matrix_CreatePyObject_wrap(float *mat,
}
PyObject *Matrix_CreatePyObject_cb(
- PyObject *cb_user, const ushort num_col, const ushort num_row, uchar cb_type, uchar cb_subtype)
+ PyObject *cb_user, const ushort col_num, const ushort row_num, uchar cb_type, uchar cb_subtype)
{
- MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, num_col, num_row, NULL);
+ MatrixObject *self = (MatrixObject *)Matrix_CreatePyObject(NULL, col_num, row_num, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
@@ -3369,12 +3367,12 @@ PyObject *Matrix_CreatePyObject_cb(
}
PyObject *Matrix_CreatePyObject_alloc(float *mat,
- const ushort num_col,
- const ushort num_row,
+ const ushort col_num,
+ const ushort row_num,
PyTypeObject *base_type)
{
MatrixObject *self;
- self = (MatrixObject *)Matrix_CreatePyObject_wrap(mat, num_col, num_row, base_type);
+ self = (MatrixObject *)Matrix_CreatePyObject_wrap(mat, col_num, row_num, base_type);
if (self) {
self->flag &= ~BASE_MATH_FLAG_IS_WRAP;
}
@@ -3419,7 +3417,7 @@ int Matrix_Parse2x2(PyObject *o, void *p)
if (!Matrix_ParseCheck(pymat)) {
return 0;
}
- if ((pymat->num_col != 2) || (pymat->num_row != 2)) {
+ if ((pymat->col_num != 2) || (pymat->row_num != 2)) {
PyErr_SetString(PyExc_ValueError, "matrix must be 2x2");
return 0;
}
@@ -3436,7 +3434,7 @@ int Matrix_Parse3x3(PyObject *o, void *p)
if (!Matrix_ParseCheck(pymat)) {
return 0;
}
- if ((pymat->num_col != 3) || (pymat->num_row != 3)) {
+ if ((pymat->col_num != 3) || (pymat->row_num != 3)) {
PyErr_SetString(PyExc_ValueError, "matrix must be 3x3");
return 0;
}
@@ -3453,7 +3451,7 @@ int Matrix_Parse4x4(PyObject *o, void *p)
if (!Matrix_ParseCheck(pymat)) {
return 0;
}
- if ((pymat->num_col != 4) || (pymat->num_row != 4)) {
+ if ((pymat->col_num != 4) || (pymat->row_num != 4)) {
PyErr_SetString(PyExc_ValueError, "matrix must be 4x4");
return 0;
}
@@ -3497,7 +3495,7 @@ static void MatrixAccess_dealloc(MatrixAccessObject *self)
static int MatrixAccess_len(MatrixAccessObject *self)
{
- return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->num_row : self->matrix_user->num_col;
+ return (self->type == MAT_ACCESS_ROW) ? self->matrix_user->row_num : self->matrix_user->col_num;
}
static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end)
@@ -3511,11 +3509,11 @@ static PyObject *MatrixAccess_slice(MatrixAccessObject *self, int begin, int end
PyObject *(*Matrix_item_new)(MatrixObject *, int);
if (self->type == MAT_ACCESS_ROW) {
- matrix_access_len = matrix_user->num_row;
+ matrix_access_len = matrix_user->row_num;
Matrix_item_new = Matrix_item_row;
}
else { /* MAT_ACCESS_ROW */
- matrix_access_len = matrix_user->num_col;
+ matrix_access_len = matrix_user->col_num;
Matrix_item_new = Matrix_item_col;
}
@@ -3546,13 +3544,13 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item
}
if (self->type == MAT_ACCESS_ROW) {
if (i < 0) {
- i += matrix_user->num_row;
+ i += matrix_user->row_num;
}
return Matrix_item_row(matrix_user, i);
}
/* MAT_ACCESS_ROW */
if (i < 0) {
- i += matrix_user->num_col;
+ i += matrix_user->col_num;
}
return Matrix_item_col(matrix_user, i);
}
@@ -3592,13 +3590,13 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item,
if (self->type == MAT_ACCESS_ROW) {
if (i < 0) {
- i += matrix_user->num_row;
+ i += matrix_user->row_num;
}
return Matrix_ass_item_row(matrix_user, i, value);
}
/* MAT_ACCESS_ROW */
if (i < 0) {
- i += matrix_user->num_col;
+ i += matrix_user->col_num;
}
return Matrix_ass_item_col(matrix_user, i, value);
}
diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h
index 6dd1640b3bf..bc596ce6ac8 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.h
+++ b/source/blender/python/mathutils/mathutils_Matrix.h
@@ -20,14 +20,14 @@ typedef unsigned short ushort;
#ifdef DEBUG
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) \
- (BLI_assert(_row < (_mat)->num_row && _col < (_mat)->num_col))
+ (BLI_assert(_row < (_mat)->row_num && _col < (_mat)->col_num))
#else
# define MATRIX_ITEM_ASSERT(_mat, _row, _col) (void)0
#endif
#define MATRIX_ITEM_INDEX_NUMROW(_totrow, _row, _col) (((_totrow) * (_col)) + (_row))
#define MATRIX_ITEM_INDEX(_mat, _row, _col) \
- (MATRIX_ITEM_ASSERT(_mat, _row, _col), (((_mat)->num_row * (_col)) + (_row)))
+ (MATRIX_ITEM_ASSERT(_mat, _row, _col), (((_mat)->row_num * (_col)) + (_row)))
#define MATRIX_ITEM_PTR(_mat, _row, _col) ((_mat)->matrix + MATRIX_ITEM_INDEX(_mat, _row, _col))
#define MATRIX_ITEM(_mat, _row, _col) ((_mat)->matrix[MATRIX_ITEM_INDEX(_mat, _row, _col)])
@@ -36,8 +36,8 @@ typedef unsigned short ushort;
typedef struct {
BASE_MATH_MEMBERS(matrix);
- ushort num_col;
- ushort num_row;
+ ushort col_num;
+ ushort row_num;
} MatrixObject;
/* struct data contains a pointer to the actual data that the
@@ -47,17 +47,17 @@ typedef struct {
/* prototypes */
PyObject *Matrix_CreatePyObject(const float *mat,
- ushort num_col,
- ushort num_row,
+ ushort col_num,
+ ushort row_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
PyObject *Matrix_CreatePyObject_wrap(float *mat,
- ushort num_col,
- ushort num_row,
+ ushort col_num,
+ ushort row_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1);
PyObject *Matrix_CreatePyObject_cb(PyObject *user,
- unsigned short num_col,
- unsigned short num_row,
+ unsigned short col_num,
+ unsigned short row_num,
unsigned char cb_type,
unsigned char cb_subtype) ATTR_WARN_UNUSED_RESULT;
@@ -65,8 +65,8 @@ PyObject *Matrix_CreatePyObject_cb(PyObject *user,
* \param mat: Initialized matrix value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Matrix_CreatePyObject_alloc(float *mat,
- ushort num_col,
- ushort num_row,
+ ushort col_num,
+ ushort row_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
/* PyArg_ParseTuple's "O&" formatting helpers. */
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index f0ba125e768..7b51154f0d0 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -1035,7 +1035,7 @@ static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2)
VectorObject *vec2 = (VectorObject *)q2;
float tvec[3];
- if (vec2->size != 3) {
+ if (vec2->vec_num != 3) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
"only 3D vector rotations (with quats) "
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 080a1e7fbdd..ffeb121b3d1 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -45,7 +45,7 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS],
static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
float *vec = NULL;
- int size = 3; /* default to a 3D vector */
+ int vec_num = 3; /* default to a 3D vector */
if (kwds && PyDict_Size(kwds)) {
PyErr_SetString(PyExc_TypeError,
@@ -56,7 +56,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
switch (PyTuple_GET_SIZE(args)) {
case 0:
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -65,10 +65,10 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL;
}
- copy_vn_fl(vec, size, 0.0f);
+ copy_vn_fl(vec, vec_num, 0.0f);
break;
case 1:
- if ((size = mathutils_array_parse_alloc(
+ if ((vec_num = mathutils_array_parse_alloc(
&vec, 2, PyTuple_GET_ITEM(args, 0), "mathutils.Vector()")) == -1) {
return NULL;
}
@@ -79,7 +79,7 @@ static PyObject *Vector_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
"more than a single arg given");
return NULL;
}
- return Vector_CreatePyObject_alloc(vec, size, type);
+ return Vector_CreatePyObject_alloc(vec, vec_num, type);
}
static PyObject *vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), VectorObject *self)
@@ -108,19 +108,19 @@ PyDoc_STRVAR(C_Vector_Fill_doc,
static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
{
float *vec;
- int size;
+ int vec_num;
float fill = 0.0f;
- if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &size, &fill)) {
+ if (!PyArg_ParseTuple(args, "i|f:Vector.Fill", &vec_num, &fill)) {
return NULL;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
return NULL;
}
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -129,9 +129,9 @@ static PyObject *C_Vector_Fill(PyObject *cls, PyObject *args)
return NULL;
}
- copy_vn_fl(vec, size, fill);
+ copy_vn_fl(vec, vec_num, fill);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Vector_Range_doc,
@@ -148,7 +148,7 @@ PyDoc_STRVAR(C_Vector_Range_doc,
static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
{
float *vec;
- int stop, size;
+ int stop, vec_num;
int start = 0;
int step = 1;
@@ -158,7 +158,7 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
switch (PyTuple_GET_SIZE(args)) {
case 1:
- size = start;
+ vec_num = start;
start = 0;
break;
case 2:
@@ -169,7 +169,7 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
return NULL;
}
- size = stop - start;
+ vec_num = stop - start;
break;
default:
if (start >= stop) {
@@ -179,23 +179,23 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
return NULL;
}
- size = (stop - start);
+ vec_num = (stop - start);
- if ((size % step) != 0) {
- size += step;
+ if ((vec_num % step) != 0) {
+ vec_num += step;
}
- size /= step;
+ vec_num /= step;
break;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
return NULL;
}
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -204,9 +204,9 @@ static PyObject *C_Vector_Range(PyObject *cls, PyObject *args)
return NULL;
}
- range_vn_fl(vec, size, (float)start, (float)step);
+ range_vn_fl(vec, vec_num, (float)start, (float)step);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
}
PyDoc_STRVAR(C_Vector_Linspace_doc,
@@ -224,21 +224,21 @@ PyDoc_STRVAR(C_Vector_Linspace_doc,
static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args)
{
float *vec;
- int size;
+ int vec_num;
float start, end, step;
- if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &size)) {
+ if (!PyArg_ParseTuple(args, "ffi:Vector.Linspace", &start, &end, &vec_num)) {
return NULL;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector.Linspace(): invalid size");
return NULL;
}
- step = (end - start) / (float)(size - 1);
+ step = (end - start) / (float)(vec_num - 1);
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -247,9 +247,9 @@ static PyObject *C_Vector_Linspace(PyObject *cls, PyObject *args)
return NULL;
}
- range_vn_fl(vec, size, start, step);
+ range_vn_fl(vec, vec_num, start, step);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
}
PyDoc_STRVAR(
@@ -266,20 +266,20 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
{
float *vec;
float *iter_vec = NULL;
- int i, size, value_size;
+ int i, vec_num, value_num;
PyObject *value;
- if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &size)) {
+ if (!PyArg_ParseTuple(args, "Oi:Vector.Repeat", &value, &vec_num)) {
return NULL;
}
- if (size < 2) {
- PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid size");
+ if (vec_num < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Vector.Repeat(): invalid vec_num");
return NULL;
}
- if ((value_size = mathutils_array_parse_alloc(
- &iter_vec, 2, value, "Vector.Repeat(vector, size), invalid 'vector' arg")) == -1) {
+ if ((value_num = mathutils_array_parse_alloc(
+ &iter_vec, 2, value, "Vector.Repeat(vector, vec_num), invalid 'vector' arg")) == -1) {
return NULL;
}
@@ -290,7 +290,7 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
return NULL;
}
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyMem_Free(iter_vec);
@@ -301,14 +301,14 @@ static PyObject *C_Vector_Repeat(PyObject *cls, PyObject *args)
}
i = 0;
- while (i < size) {
- vec[i] = iter_vec[i % value_size];
+ while (i < vec_num) {
+ vec[i] = iter_vec[i % value_num];
i++;
}
PyMem_Free(iter_vec);
- return Vector_CreatePyObject_alloc(vec, size, (PyTypeObject *)cls);
+ return Vector_CreatePyObject_alloc(vec, vec_num, (PyTypeObject *)cls);
}
/*-----------------------------METHODS---------------------------- */
@@ -322,7 +322,7 @@ static PyObject *Vector_zero(VectorObject *self)
return NULL;
}
- copy_vn_fl(self->vec, self->size, 0.0f);
+ copy_vn_fl(self->vec, self->vec_num, 0.0f);
if (BaseMath_WriteCallback(self) == -1) {
return NULL;
@@ -342,12 +342,12 @@ PyDoc_STRVAR(Vector_normalize_doc,
" however 4D Vectors w axis is left untouched.\n");
static PyObject *Vector_normalize(VectorObject *self)
{
- const int size = (self->size == 4 ? 3 : self->size);
+ const int vec_num = (self->vec_num == 4 ? 3 : self->vec_num);
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
return NULL;
}
- normalize_vn(self->vec, size);
+ normalize_vn(self->vec, vec_num);
(void)BaseMath_WriteCallback(self);
Py_RETURN_NONE;
@@ -370,7 +370,7 @@ PyDoc_STRVAR(Vector_resize_doc,
" Resize the vector to have size number of elements.\n");
static PyObject *Vector_resize(VectorObject *self, PyObject *value)
{
- int size;
+ int vec_num;
if (self->flag & BASE_MATH_FLAG_IS_WRAP) {
PyErr_SetString(PyExc_TypeError,
@@ -385,19 +385,19 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value)
return NULL;
}
- if ((size = PyC_Long_AsI32(value)) == -1) {
+ if ((vec_num = PyC_Long_AsI32(value)) == -1) {
PyErr_SetString(PyExc_TypeError,
"Vector.resize(size): "
"expected size argument to be an integer");
return NULL;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector.resize(): invalid size");
return NULL;
}
- self->vec = PyMem_Realloc(self->vec, (size * sizeof(float)));
+ self->vec = PyMem_Realloc(self->vec, (vec_num * sizeof(float)));
if (self->vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Vector.resize(): "
@@ -406,11 +406,11 @@ static PyObject *Vector_resize(VectorObject *self, PyObject *value)
}
/* If the vector has increased in length, set all new elements to 0.0f */
- if (size > self->size) {
- copy_vn_fl(self->vec + self->size, size - self->size, 0.0f);
+ if (vec_num > self->vec_num) {
+ copy_vn_fl(self->vec + self->vec_num, vec_num - self->vec_num, 0.0f);
}
- self->size = size;
+ self->vec_num = vec_num;
Py_RETURN_NONE;
}
@@ -423,19 +423,19 @@ PyDoc_STRVAR(Vector_resized_doc,
" :rtype: :class:`Vector`\n");
static PyObject *Vector_resized(VectorObject *self, PyObject *value)
{
- int size;
+ int vec_num;
float *vec;
- if ((size = PyLong_AsLong(value)) == -1) {
+ if ((vec_num = PyLong_AsLong(value)) == -1) {
return NULL;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector.resized(): invalid size");
return NULL;
}
- vec = PyMem_Malloc(size * sizeof(float));
+ vec = PyMem_Malloc(vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -444,10 +444,10 @@ static PyObject *Vector_resized(VectorObject *self, PyObject *value)
return NULL;
}
- copy_vn_fl(vec, size, 0.0f);
- memcpy(vec, self->vec, self->size * sizeof(float));
+ copy_vn_fl(vec, vec_num, 0.0f);
+ memcpy(vec, self->vec, self->vec_num * sizeof(float));
- return Vector_CreatePyObject_alloc(vec, size, NULL);
+ return Vector_CreatePyObject_alloc(vec, vec_num, NULL);
}
PyDoc_STRVAR(Vector_resize_2d_doc,
@@ -477,7 +477,7 @@ static PyObject *Vector_resize_2d(VectorObject *self)
return NULL;
}
- self->size = 2;
+ self->vec_num = 2;
Py_RETURN_NONE;
}
@@ -508,11 +508,11 @@ static PyObject *Vector_resize_3d(VectorObject *self)
return NULL;
}
- if (self->size == 2) {
+ if (self->vec_num == 2) {
self->vec[2] = 0.0f;
}
- self->size = 3;
+ self->vec_num = 3;
Py_RETURN_NONE;
}
@@ -543,14 +543,14 @@ static PyObject *Vector_resize_4d(VectorObject *self)
return NULL;
}
- if (self->size == 2) {
+ if (self->vec_num == 2) {
self->vec[2] = 0.0f;
self->vec[3] = 1.0f;
}
- else if (self->size == 3) {
+ else if (self->vec_num == 3) {
self->vec[3] = 1.0f;
}
- self->size = 4;
+ self->vec_num = 4;
Py_RETURN_NONE;
}
PyDoc_STRVAR(Vector_to_2d_doc,
@@ -583,7 +583,7 @@ static PyObject *Vector_to_3d(VectorObject *self)
return NULL;
}
- memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 3));
+ memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 3));
return Vector_CreatePyObject(tvec, 3, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_to_4d_doc,
@@ -601,7 +601,7 @@ static PyObject *Vector_to_4d(VectorObject *self)
return NULL;
}
- memcpy(tvec, self->vec, sizeof(float) * MIN2(self->size, 4));
+ memcpy(tvec, self->vec, sizeof(float) * MIN2(self->vec_num, 4));
return Vector_CreatePyObject(tvec, 4, Py_TYPE(self));
}
@@ -620,15 +620,15 @@ static PyObject *Vector_to_tuple_ex(VectorObject *self, int ndigits)
PyObject *ret;
int i;
- ret = PyTuple_New(self->size);
+ ret = PyTuple_New(self->vec_num);
if (ndigits >= 0) {
- for (i = 0; i < self->size; i++) {
+ for (i = 0; i < self->vec_num; i++) {
PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(double_round((double)self->vec[i], ndigits)));
}
}
else {
- for (i = 0; i < self->size; i++) {
+ for (i = 0; i < self->vec_num; i++) {
PyTuple_SET_ITEM(ret, i, PyFloat_FromDouble(self->vec[i]));
}
}
@@ -684,7 +684,7 @@ static PyObject *Vector_to_track_quat(VectorObject *self, PyObject *args)
return NULL;
}
- if (self->size != 3) {
+ if (self->vec_num != 3) {
PyErr_SetString(PyExc_TypeError,
"Vector.to_track_quat(): "
"only for 3D vectors");
@@ -795,7 +795,7 @@ static PyObject *Vector_orthogonal(VectorObject *self)
{
float vec[3];
- if (self->size > 3) {
+ if (self->vec_num > 3) {
PyErr_SetString(PyExc_TypeError,
"Vector.orthogonal(): "
"Vector must be 3D or 2D");
@@ -806,14 +806,14 @@ static PyObject *Vector_orthogonal(VectorObject *self)
return NULL;
}
- if (self->size == 3) {
+ if (self->vec_num == 3) {
ortho_v3_v3(vec, self->vec);
}
else {
ortho_v2_v2(vec, self->vec);
}
- return Vector_CreatePyObject(vec, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(vec, self->vec_num, Py_TYPE(self));
}
/**
@@ -833,7 +833,7 @@ PyDoc_STRVAR(Vector_reflect_doc,
" :rtype: :class:`Vector`\n");
static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
{
- int value_size;
+ int value_num;
float mirror[3], vec[3];
float reflect[3] = {0.0f};
float tvec[MAX_DIMENSIONS];
@@ -842,28 +842,28 @@ static PyObject *Vector_reflect(VectorObject *self, PyObject *value)
return NULL;
}
- if ((value_size = mathutils_array_parse(
+ if ((value_num = mathutils_array_parse(
tvec, 2, 4, value, "Vector.reflect(other), invalid 'other' arg")) == -1) {
return NULL;
}
- if (self->size < 2 || self->size > 4) {
+ if (self->vec_num < 2 || self->vec_num > 4) {
PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
return NULL;
}
mirror[0] = tvec[0];
mirror[1] = tvec[1];
- mirror[2] = (value_size > 2) ? tvec[2] : 0.0f;
+ mirror[2] = (value_num > 2) ? tvec[2] : 0.0f;
vec[0] = self->vec[0];
vec[1] = self->vec[1];
- vec[2] = (value_size > 2) ? self->vec[2] : 0.0f;
+ vec[2] = (value_num > 2) ? self->vec[2] : 0.0f;
normalize_v3(mirror);
reflect_v3_v3v3(reflect, vec, mirror);
- return Vector_CreatePyObject(reflect, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(reflect, self->vec_num, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_cross_doc,
@@ -886,17 +886,18 @@ static PyObject *Vector_cross(VectorObject *self, PyObject *value)
return NULL;
}
- if (self->size > 3) {
+ if (self->vec_num > 3) {
PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
return NULL;
}
if (mathutils_array_parse(
- tvec, self->size, self->size, value, "Vector.cross(other), invalid 'other' arg") == -1) {
+ tvec, self->vec_num, self->vec_num, value, "Vector.cross(other), invalid 'other' arg") ==
+ -1) {
return NULL;
}
- if (self->size == 3) {
+ if (self->vec_num == 3) {
ret = Vector_CreatePyObject(NULL, 3, Py_TYPE(self));
cross_v3_v3v3(((VectorObject *)ret)->vec, self->vec, tvec);
}
@@ -926,11 +927,11 @@ static PyObject *Vector_dot(VectorObject *self, PyObject *value)
}
if (mathutils_array_parse_alloc(
- &tvec, self->size, value, "Vector.dot(other), invalid 'other' arg") == -1) {
+ &tvec, self->vec_num, value, "Vector.dot(other), invalid 'other' arg") == -1) {
return NULL;
}
- ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->size));
+ ret = PyFloat_FromDouble(dot_vn_vn(self->vec, tvec, self->vec_num));
PyMem_Free(tvec);
return ret;
}
@@ -950,7 +951,7 @@ PyDoc_STRVAR(
" :rtype: float\n");
static PyObject *Vector_angle(VectorObject *self, PyObject *args)
{
- const int size = MIN2(self->size, 3); /* 4D angle makes no sense */
+ const int vec_num = MIN2(self->vec_num, 3); /* 4D angle makes no sense */
float tvec[MAX_DIMENSIONS];
PyObject *value;
double dot = 0.0f, dot_self = 0.0f, dot_other = 0.0f;
@@ -968,16 +969,17 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
/* don't use clamped size, rule of thumb is vector sizes must match,
* even though n this case 'w' is ignored */
if (mathutils_array_parse(
- tvec, self->size, self->size, value, "Vector.angle(other), invalid 'other' arg") == -1) {
+ tvec, self->vec_num, self->vec_num, value, "Vector.angle(other), invalid 'other' arg") ==
+ -1) {
return NULL;
}
- if (self->size > 4) {
+ if (self->vec_num > 4) {
PyErr_SetString(PyExc_ValueError, "Vector must be 2D, 3D or 4D");
return NULL;
}
- for (x = 0; x < size; x++) {
+ for (x = 0; x < vec_num; x++) {
dot_self += (double)self->vec[x] * (double)self->vec[x];
dot_other += (double)tvec[x] * (double)tvec[x];
dot += (double)self->vec[x] * (double)tvec[x];
@@ -1032,7 +1034,7 @@ static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args)
return NULL;
}
- if (self->size != 2) {
+ if (self->vec_num != 2) {
PyErr_SetString(PyExc_ValueError, "Vector must be 2D");
return NULL;
}
@@ -1069,7 +1071,7 @@ static PyObject *Vector_rotation_difference(VectorObject *self, PyObject *value)
{
float quat[4], vec_a[3], vec_b[3];
- if (self->size < 3 || self->size > 4) {
+ if (self->vec_num < 3 || self->vec_num > 4) {
PyErr_SetString(PyExc_ValueError,
"vec.difference(value): "
"expects both vectors to be size 3 or 4");
@@ -1105,7 +1107,7 @@ PyDoc_STRVAR(Vector_project_doc,
" :rtype: :class:`Vector`\n");
static PyObject *Vector_project(VectorObject *self, PyObject *value)
{
- const int size = self->size;
+ const int vec_num = self->vec_num;
float *tvec;
double dot = 0.0f, dot2 = 0.0f;
int x;
@@ -1115,21 +1117,21 @@ static PyObject *Vector_project(VectorObject *self, PyObject *value)
}
if (mathutils_array_parse_alloc(
- &tvec, size, value, "Vector.project(other), invalid 'other' arg") == -1) {
+ &tvec, vec_num, value, "Vector.project(other), invalid 'other' arg") == -1) {
return NULL;
}
/* get dot products */
- for (x = 0; x < size; x++) {
+ for (x = 0; x < vec_num; x++) {
dot += (double)(self->vec[x] * tvec[x]);
dot2 += (double)(tvec[x] * tvec[x]);
}
/* projection */
dot /= dot2;
- for (x = 0; x < size; x++) {
+ for (x = 0; x < vec_num; x++) {
tvec[x] *= (float)dot;
}
- return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
+ return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_lerp_doc,
@@ -1145,7 +1147,7 @@ PyDoc_STRVAR(Vector_lerp_doc,
" :rtype: :class:`Vector`\n");
static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
{
- const int size = self->size;
+ const int vec_num = self->vec_num;
PyObject *value = NULL;
float fac;
float *tvec;
@@ -1158,14 +1160,14 @@ static PyObject *Vector_lerp(VectorObject *self, PyObject *args)
return NULL;
}
- if (mathutils_array_parse_alloc(&tvec, size, value, "Vector.lerp(other), invalid 'other' arg") ==
- -1) {
+ if (mathutils_array_parse_alloc(
+ &tvec, vec_num, value, "Vector.lerp(other), invalid 'other' arg") == -1) {
return NULL;
}
- interp_vn_vn(tvec, self->vec, 1.0f - fac, size);
+ interp_vn_vn(tvec, self->vec, 1.0f - fac, vec_num);
- return Vector_CreatePyObject_alloc(tvec, size, Py_TYPE(self));
+ return Vector_CreatePyObject_alloc(tvec, vec_num, Py_TYPE(self));
}
PyDoc_STRVAR(Vector_slerp_doc,
@@ -1185,7 +1187,7 @@ PyDoc_STRVAR(Vector_slerp_doc,
" :rtype: :class:`Vector`\n");
static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
{
- const int size = self->size;
+ const int vec_num = self->vec_num;
PyObject *value = NULL;
float fac, cosom, w[2];
float self_vec[3], other_vec[3], ret_vec[3];
@@ -1201,18 +1203,18 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
return NULL;
}
- if (self->size > 3) {
+ if (self->vec_num > 3) {
PyErr_SetString(PyExc_ValueError, "Vector must be 2D or 3D");
return NULL;
}
if (mathutils_array_parse(
- other_vec, size, size, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
+ other_vec, vec_num, vec_num, value, "Vector.slerp(other), invalid 'other' arg") == -1) {
return NULL;
}
- self_len_sq = normalize_vn_vn(self_vec, self->vec, size);
- other_len_sq = normalize_vn(other_vec, size);
+ self_len_sq = normalize_vn_vn(self_vec, self->vec, vec_num);
+ other_len_sq = normalize_vn(other_vec, vec_num);
/* use fallbacks for zero length vectors */
if (UNLIKELY((self_len_sq < FLT_EPSILON) || (other_len_sq < FLT_EPSILON))) {
@@ -1229,7 +1231,7 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
}
/* We have sane state, execute slerp */
- cosom = (float)dot_vn_vn(self_vec, other_vec, size);
+ cosom = (float)dot_vn_vn(self_vec, other_vec, vec_num);
/* direct opposite, can't slerp */
if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
@@ -1247,11 +1249,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
interp_dot_slerp(fac, cosom, w);
- for (x = 0; x < size; x++) {
+ for (x = 0; x < vec_num; x++) {
ret_vec[x] = (w[0] * self_vec[x]) + (w[1] * other_vec[x]);
}
- return Vector_CreatePyObject(ret_vec, size, Py_TYPE(self));
+ return Vector_CreatePyObject(ret_vec, vec_num, Py_TYPE(self));
}
PyDoc_STRVAR(
@@ -1270,7 +1272,7 @@ static PyObject *Vector_rotate(VectorObject *self, PyObject *value)
return NULL;
}
- if (self->size == 2) {
+ if (self->vec_num == 2) {
/* Special case for 2D Vector with 2x2 matrix, so we avoid resizing it to a 3x3. */
float other_rmat[2][2];
MatrixObject *pymat;
@@ -1311,7 +1313,7 @@ static PyObject *Vector_copy(VectorObject *self)
return NULL;
}
- return Vector_CreatePyObject(self->vec, self->size, Py_TYPE(self));
+ return Vector_CreatePyObject(self->vec, self->vec_num, Py_TYPE(self));
}
static PyObject *Vector_deepcopy(VectorObject *self, PyObject *args)
{
@@ -1350,7 +1352,7 @@ static PyObject *Vector_str(VectorObject *self)
BLI_dynstr_append(ds, "<Vector (");
- for (i = 0; i < self->size; i++) {
+ for (i = 0; i < self->vec_num; i++) {
BLI_dynstr_appendf(ds, i ? ", %.4f" : "%.4f", self->vec[i]);
}
@@ -1364,21 +1366,21 @@ static PyObject *Vector_str(VectorObject *self)
/* sequence length len(vector) */
static int Vector_len(VectorObject *self)
{
- return self->size;
+ return self->vec_num;
}
/* sequence accessor (get): vector[index] */
static PyObject *vector_item_internal(VectorObject *self, int i, const bool is_attr)
{
if (i < 0) {
- i = self->size - i;
+ i = self->vec_num - i;
}
- if (i < 0 || i >= self->size) {
+ if (i < 0 || i >= self->vec_num) {
if (is_attr) {
PyErr_Format(PyExc_AttributeError,
"Vector.%c: unavailable on %dd vector",
*(((const char *)"xyzw") + i),
- self->size);
+ self->vec_num);
}
else {
PyErr_SetString(PyExc_IndexError, "vector[index]: out of range");
@@ -1415,15 +1417,15 @@ static int vector_ass_item_internal(VectorObject *self, int i, PyObject *value,
}
if (i < 0) {
- i = self->size - i;
+ i = self->vec_num - i;
}
- if (i < 0 || i >= self->size) {
+ if (i < 0 || i >= self->vec_num) {
if (is_attr) {
PyErr_Format(PyExc_AttributeError,
"Vector.%c = x: unavailable on %dd vector",
*(((const char *)"xyzw") + i),
- self->size);
+ self->vec_num);
}
else {
PyErr_SetString(PyExc_IndexError,
@@ -1455,11 +1457,11 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end)
return NULL;
}
- CLAMP(begin, 0, self->size);
+ CLAMP(begin, 0, self->vec_num);
if (end < 0) {
- end = self->size + end + 1;
+ end = self->vec_num + end + 1;
}
- CLAMP(end, 0, self->size);
+ CLAMP(end, 0, self->vec_num);
begin = MIN2(begin, end);
tuple = PyTuple_New(end - begin);
@@ -1472,19 +1474,19 @@ static PyObject *Vector_slice(VectorObject *self, int begin, int end)
/* sequence slice (set): vector[a:b] = value */
static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
{
- int size = 0;
+ int vec_num = 0;
float *vec = NULL;
if (BaseMath_ReadCallback_ForWrite(self) == -1) {
return -1;
}
- CLAMP(begin, 0, self->size);
- CLAMP(end, 0, self->size);
+ CLAMP(begin, 0, self->vec_num);
+ CLAMP(end, 0, self->vec_num);
begin = MIN2(begin, end);
- size = (end - begin);
- if (mathutils_array_parse_alloc(&vec, size, seq, "vector[begin:end] = [...]") == -1) {
+ vec_num = (end - begin);
+ if (mathutils_array_parse_alloc(&vec, vec_num, seq, "vector[begin:end] = [...]") == -1) {
return -1;
}
@@ -1496,7 +1498,7 @@ static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *se
}
/* Parsed well - now set in vector. */
- memcpy(self->vec + begin, vec, size * sizeof(float));
+ memcpy(self->vec + begin, vec, vec_num * sizeof(float));
PyMem_Free(vec);
@@ -1530,14 +1532,14 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2)
}
/* VECTOR + VECTOR. */
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector addition: "
"vectors must have the same dimensions for this operation");
return NULL;
}
- vec = PyMem_Malloc(vec1->size * sizeof(float));
+ vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Vector(): "
@@ -1545,9 +1547,9 @@ static PyObject *Vector_add(PyObject *v1, PyObject *v2)
return NULL;
}
- add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
+ add_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num);
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
}
/* addition in-place: obj += obj */
@@ -1566,7 +1568,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
vec1 = (VectorObject *)v1;
vec2 = (VectorObject *)v2;
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector addition: "
"vectors must have the same dimensions for this operation");
@@ -1577,7 +1579,7 @@ static PyObject *Vector_iadd(PyObject *v1, PyObject *v2)
return NULL;
}
- add_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ add_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
(void)BaseMath_WriteCallback(vec1);
Py_INCREF(v1);
@@ -1605,14 +1607,14 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
return NULL;
}
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector subtraction: "
"vectors must have the same dimensions for this operation");
return NULL;
}
- vec = PyMem_Malloc(vec1->size * sizeof(float));
+ vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"Vector(): "
@@ -1620,9 +1622,9 @@ static PyObject *Vector_sub(PyObject *v1, PyObject *v2)
return NULL;
}
- sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->size);
+ sub_vn_vnvn(vec, vec1->vec, vec2->vec, vec1->vec_num);
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
}
/* subtraction in-place: obj -= obj */
@@ -1641,7 +1643,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
vec1 = (VectorObject *)v1;
vec2 = (VectorObject *)v2;
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector subtraction: "
"vectors must have the same dimensions for this operation");
@@ -1652,7 +1654,7 @@ static PyObject *Vector_isub(PyObject *v1, PyObject *v2)
return NULL;
}
- sub_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ sub_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
(void)BaseMath_WriteCallback(vec1);
Py_INCREF(v1);
@@ -1667,8 +1669,8 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec,
float vec_cpy[MAX_DIMENSIONS];
int row, col, z = 0;
- if (mat->num_col != vec->size) {
- if (mat->num_col == 4 && vec->size == 3) {
+ if (mat->col_num != vec->vec_num) {
+ if (mat->col_num == 4 && vec->vec_num == 3) {
vec_cpy[3] = 1.0f;
}
else {
@@ -1680,13 +1682,13 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec,
}
}
- memcpy(vec_cpy, vec->vec, vec->size * sizeof(float));
+ memcpy(vec_cpy, vec->vec, vec->vec_num * sizeof(float));
r_vec[3] = 1.0f;
- for (row = 0; row < mat->num_row; row++) {
+ for (row = 0; row < mat->row_num; row++) {
double dot = 0.0f;
- for (col = 0; col < mat->num_col; col++) {
+ for (col = 0; col < mat->col_num; col++) {
dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[col]);
}
r_vec[z++] = (float)dot;
@@ -1697,7 +1699,7 @@ int column_vector_multiplication(float r_vec[MAX_DIMENSIONS], VectorObject *vec,
static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
{
- float *tvec = PyMem_Malloc(vec->size * sizeof(float));
+ float *tvec = PyMem_Malloc(vec->vec_num * sizeof(float));
if (tvec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"vec * float: "
@@ -1705,13 +1707,13 @@ static PyObject *vector_mul_float(VectorObject *vec, const float scalar)
return NULL;
}
- mul_vn_vn_fl(tvec, vec->vec, vec->size, scalar);
- return Vector_CreatePyObject_alloc(tvec, vec->size, Py_TYPE(vec));
+ mul_vn_vn_fl(tvec, vec->vec, vec->vec_num, scalar);
+ return Vector_CreatePyObject_alloc(tvec, vec->vec_num, Py_TYPE(vec));
}
static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
{
- float *tvec = PyMem_Malloc(vec1->size * sizeof(float));
+ float *tvec = PyMem_Malloc(vec1->vec_num * sizeof(float));
if (tvec == NULL) {
PyErr_SetString(PyExc_MemoryError,
"vec * vec: "
@@ -1719,8 +1721,8 @@ static PyObject *vector_mul_vec(VectorObject *vec1, VectorObject *vec2)
return NULL;
}
- mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->size);
- return Vector_CreatePyObject_alloc(tvec, vec1->size, Py_TYPE(vec1));
+ mul_vn_vnvn(tvec, vec1->vec, vec2->vec, vec1->vec_num);
+ return Vector_CreatePyObject_alloc(tvec, vec1->vec_num, Py_TYPE(vec1));
}
static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
@@ -1745,7 +1747,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
/* make sure v1 is always the vector */
if (vec1 && vec2) {
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
"vectors must have the same dimensions for this operation");
@@ -1800,7 +1802,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
/* Intentionally don't support (Quaternion, Matrix) here, uses reverse order instead. */
if (vec1 && vec2) {
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
"vectors must have the same dimensions for this operation");
@@ -1808,11 +1810,11 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
}
/* Element-wise product in-place. */
- mul_vn_vn(vec1->vec, vec2->vec, vec1->size);
+ mul_vn_vn(vec1->vec, vec2->vec, vec1->vec_num);
}
else if (vec1 && (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) ==
0)) { /* VEC *= FLOAT */
- mul_vn_fl(vec1->vec, vec1->size, scalar);
+ mul_vn_fl(vec1->vec, vec1->vec_num, scalar);
}
else {
PyErr_Format(PyExc_TypeError,
@@ -1831,7 +1833,7 @@ static PyObject *Vector_imul(PyObject *v1, PyObject *v2)
static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
{
VectorObject *vec1 = NULL, *vec2 = NULL;
- int vec_size;
+ int vec_num;
if (VectorObject_Check(v1)) {
vec1 = (VectorObject *)v1;
@@ -1850,7 +1852,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
/* make sure v1 is always the vector */
if (vec1 && vec2) {
- if (vec1->size != vec2->size) {
+ if (vec1->vec_num != vec2->vec_num) {
PyErr_SetString(PyExc_ValueError,
"Vector multiplication: "
"vectors must have the same dimensions for this operation");
@@ -1858,7 +1860,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
}
/* Dot product. */
- return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size));
+ return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->vec_num));
}
if (vec1) {
if (MatrixObject_Check(v2)) {
@@ -1872,14 +1874,14 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
return NULL;
}
- if (((MatrixObject *)v2)->num_row == 4 && vec1->size == 3) {
- vec_size = 3;
+ if (((MatrixObject *)v2)->row_num == 4 && vec1->vec_num == 3) {
+ vec_num = 3;
}
else {
- vec_size = ((MatrixObject *)v2)->num_col;
+ vec_num = ((MatrixObject *)v2)->col_num;
}
- return Vector_CreatePyObject(tvec, vec_size, Py_TYPE(vec1));
+ return Vector_CreatePyObject(tvec, vec_num, Py_TYPE(vec1));
}
}
@@ -1934,7 +1936,7 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2)
return NULL;
}
- vec = PyMem_Malloc(vec1->size * sizeof(float));
+ vec = PyMem_Malloc(vec1->vec_num * sizeof(float));
if (vec == NULL) {
PyErr_SetString(PyExc_MemoryError,
@@ -1943,9 +1945,9 @@ static PyObject *Vector_div(PyObject *v1, PyObject *v2)
return NULL;
}
- mul_vn_vn_fl(vec, vec1->vec, vec1->size, 1.0f / scalar);
+ mul_vn_vn_fl(vec, vec1->vec, vec1->vec_num, 1.0f / scalar);
- return Vector_CreatePyObject_alloc(vec, vec1->size, Py_TYPE(v1));
+ return Vector_CreatePyObject_alloc(vec, vec1->vec_num, Py_TYPE(v1));
}
/* divide in-place: obj /= obj */
@@ -1973,7 +1975,7 @@ static PyObject *Vector_idiv(PyObject *v1, PyObject *v2)
return NULL;
}
- mul_vn_fl(vec1->vec, vec1->size, 1.0f / scalar);
+ mul_vn_fl(vec1->vec, vec1->vec_num, 1.0f / scalar);
(void)BaseMath_WriteCallback(vec1);
@@ -1991,9 +1993,9 @@ static PyObject *Vector_neg(VectorObject *self)
return NULL;
}
- tvec = PyMem_Malloc(self->size * sizeof(float));
- negate_vn_vn(tvec, self->vec, self->size);
- return Vector_CreatePyObject_alloc(tvec, self->size, Py_TYPE(self));
+ tvec = PyMem_Malloc(self->vec_num * sizeof(float));
+ negate_vn_vn(tvec, self->vec, self->vec_num);
+ return Vector_CreatePyObject_alloc(tvec, self->vec_num, Py_TYPE(self));
}
/*------------------------tp_richcmpr
@@ -2019,7 +2021,7 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
return NULL;
}
- if (vecA->size != vecB->size) {
+ if (vecA->vec_num != vecB->vec_num) {
if (comparison_type == Py_NE) {
Py_RETURN_TRUE;
}
@@ -2029,15 +2031,15 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
switch (comparison_type) {
case Py_LT:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->vec_num);
+ lenB = len_squared_vn(vecB->vec, vecB->vec_num);
if (lenA < lenB) {
result = 1;
}
break;
case Py_LE:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->vec_num);
+ lenB = len_squared_vn(vecB->vec, vecB->vec_num);
if (lenA < lenB) {
result = 1;
}
@@ -2046,21 +2048,21 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
}
break;
case Py_EQ:
- result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
+ result = EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1);
break;
case Py_NE:
- result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->size, 1);
+ result = !EXPP_VectorsAreEqual(vecA->vec, vecB->vec, vecA->vec_num, 1);
break;
case Py_GT:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->vec_num);
+ lenB = len_squared_vn(vecB->vec, vecB->vec_num);
if (lenA > lenB) {
result = 1;
}
break;
case Py_GE:
- lenA = len_squared_vn(vecA->vec, vecA->size);
- lenB = len_squared_vn(vecB->vec, vecB->size);
+ lenA = len_squared_vn(vecA->vec, vecA->vec_num);
+ lenB = len_squared_vn(vecB->vec, vecB->vec_num);
if (lenA > lenB) {
result = 1;
}
@@ -2089,7 +2091,7 @@ static Py_hash_t Vector_hash(VectorObject *self)
return -1;
}
- return mathutils_array_hash(self->vec, self->size);
+ return mathutils_array_hash(self->vec, self->vec_num);
}
/*-----------------PROTCOL DECLARATIONS--------------------------*/
@@ -2115,14 +2117,14 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item)
return NULL;
}
if (i < 0) {
- i += self->size;
+ i += self->vec_num;
}
return Vector_item(self, i);
}
if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
+ if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) {
return NULL;
}
@@ -2150,14 +2152,14 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va
return -1;
}
if (i < 0) {
- i += self->size;
+ i += self->vec_num;
}
return Vector_ass_item(self, i, value);
}
if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
- if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
+ if (PySlice_GetIndicesEx(item, self->vec_num, &start, &stop, &step, &slicelength) < 0) {
return -1;
}
@@ -2247,7 +2249,7 @@ static PyObject *Vector_length_get(VectorObject *self, void *UNUSED(closure))
return NULL;
}
- return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->size)));
+ return PyFloat_FromDouble(sqrt(dot_vn_vn(self->vec, self->vec, self->vec_num)));
}
static int Vector_length_set(VectorObject *self, PyObject *value)
@@ -2268,11 +2270,11 @@ static int Vector_length_set(VectorObject *self, PyObject *value)
return -1;
}
if (param == 0.0) {
- copy_vn_fl(self->vec, self->size, 0.0f);
+ copy_vn_fl(self->vec, self->vec_num, 0.0f);
return 0;
}
- dot = dot_vn_vn(self->vec, self->vec, self->size);
+ dot = dot_vn_vn(self->vec, self->vec, self->vec_num);
if (!dot) {
/* can't sqrt zero */
@@ -2287,7 +2289,7 @@ static int Vector_length_set(VectorObject *self, PyObject *value)
dot = dot / param;
- mul_vn_fl(self->vec, self->size, 1.0 / dot);
+ mul_vn_fl(self->vec, self->vec_num, 1.0 / dot);
(void)BaseMath_WriteCallback(self); /* checked already */
@@ -2302,7 +2304,7 @@ static PyObject *Vector_length_squared_get(VectorObject *self, void *UNUSED(clos
return NULL;
}
- return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->size));
+ return PyFloat_FromDouble(dot_vn_vn(self->vec, self->vec, self->vec_num));
}
/**
@@ -2382,7 +2384,7 @@ static PyObject *Vector_swizzle_get(VectorObject *self, void *closure)
swizzleClosure = POINTER_AS_INT(closure);
while (swizzleClosure & SWIZZLE_VALID_AXIS) {
axis_from = swizzleClosure & SWIZZLE_AXIS;
- if (axis_from >= self->size) {
+ if (axis_from >= self->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector swizzle: "
"specified axis not present");
@@ -2432,7 +2434,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
while (swizzleClosure & SWIZZLE_VALID_AXIS) {
axis_to = swizzleClosure & SWIZZLE_AXIS;
- if (axis_to >= self->size) {
+ if (axis_to >= self->vec_num) {
PyErr_SetString(PyExc_AttributeError,
"Vector swizzle: "
"specified axis not present");
@@ -2468,8 +2470,8 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
/* We must first copy current vec into tvec, else some org values may be lost.
* See T31760.
- * Assuming self->size can't be higher than MAX_DIMENSIONS! */
- memcpy(tvec, self->vec, self->size * sizeof(float));
+ * Assuming self->vec_num can't be higher than MAX_DIMENSIONS! */
+ memcpy(tvec, self->vec, self->vec_num * sizeof(float));
while (swizzleClosure & SWIZZLE_VALID_AXIS) {
axis_to = swizzleClosure & SWIZZLE_AXIS;
@@ -2480,7 +2482,7 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
/* We must copy back the whole tvec into vec, else some changes may be lost (e.g. xz...).
* See T31760. */
- memcpy(self->vec, tvec, self->size * sizeof(float));
+ memcpy(self->vec, tvec, self->vec_num * sizeof(float));
/* continue with BaseMathObject_WriteCallback at the end */
if (BaseMath_WriteCallback(self) == -1) {
@@ -2898,10 +2900,10 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS],
MatrixObject *mat)
{
float vec_cpy[MAX_DIMENSIONS];
- int row, col, z = 0, vec_size = vec->size;
+ int row, col, z = 0, vec_num = vec->vec_num;
- if (mat->num_row != vec_size) {
- if (mat->num_row == 4 && vec_size == 3) {
+ if (mat->row_num != vec_num) {
+ if (mat->row_num == 4 && vec_num == 3) {
vec_cpy[3] = 1.0f;
}
else {
@@ -2916,13 +2918,13 @@ static int row_vector_multiplication(float r_vec[MAX_DIMENSIONS],
return -1;
}
- memcpy(vec_cpy, vec->vec, vec_size * sizeof(float));
+ memcpy(vec_cpy, vec->vec, vec_num * sizeof(float));
r_vec[3] = 1.0f;
/* Multiplication. */
- for (col = 0; col < mat->num_col; col++) {
+ for (col = 0; col < mat->col_num; col++) {
double dot = 0.0;
- for (row = 0; row < mat->num_row; row++) {
+ for (row = 0; row < mat->row_num; row++) {
dot += (double)(MATRIX_ITEM(mat, row, col) * vec_cpy[row]);
}
r_vec[z++] = (float)dot;
@@ -2941,7 +2943,7 @@ static PyObject *Vector_negate(VectorObject *self)
return NULL;
}
- negate_vn(self->vec, self->size);
+ negate_vn(self->vec, self->vec_num);
(void)BaseMath_WriteCallback(self); /* already checked for error */
Py_RETURN_NONE;
@@ -3096,17 +3098,17 @@ PyTypeObject vector_Type = {
NULL,
};
-PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject(const float *vec, const int vec_num, PyTypeObject *base_type)
{
VectorObject *self;
float *vec_alloc;
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
return NULL;
}
- vec_alloc = PyMem_Malloc(size * sizeof(float));
+ vec_alloc = PyMem_Malloc(vec_num * sizeof(float));
if (UNLIKELY(vec_alloc == NULL)) {
PyErr_SetString(PyExc_MemoryError,
"Vector(): "
@@ -3117,18 +3119,18 @@ PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *
self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
if (self) {
self->vec = vec_alloc;
- self->size = size;
+ self->vec_num = vec_num;
/* init callbacks as NULL */
self->cb_user = NULL;
self->cb_type = self->cb_subtype = 0;
if (vec) {
- memcpy(self->vec, vec, size * sizeof(float));
+ memcpy(self->vec, vec, vec_num * sizeof(float));
}
else { /* new empty */
- copy_vn_fl(self->vec, size, 0.0f);
- if (size == 4) { /* do the homogeneous thing */
+ copy_vn_fl(self->vec, vec_num, 0.0f);
+ if (vec_num == 4) { /* do the homogeneous thing */
self->vec[3] = 1.0f;
}
}
@@ -3141,18 +3143,18 @@ PyObject *Vector_CreatePyObject(const float *vec, const int size, PyTypeObject *
return (PyObject *)self;
}
-PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_wrap(float *vec, const int vec_num, PyTypeObject *base_type)
{
VectorObject *self;
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_RuntimeError, "Vector(): invalid size");
return NULL;
}
self = BASE_MATH_NEW(VectorObject, vector_Type, base_type);
if (self) {
- self->size = size;
+ self->vec_num = vec_num;
/* init callbacks as NULL */
self->cb_user = NULL;
@@ -3164,9 +3166,9 @@ PyObject *Vector_CreatePyObject_wrap(float *vec, const int size, PyTypeObject *b
return (PyObject *)self;
}
-PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, uchar cb_subtype)
+PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int vec_num, uchar cb_type, uchar cb_subtype)
{
- VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, size, NULL);
+ VectorObject *self = (VectorObject *)Vector_CreatePyObject(NULL, vec_num, NULL);
if (self) {
Py_INCREF(cb_user);
self->cb_user = cb_user;
@@ -3178,10 +3180,10 @@ PyObject *Vector_CreatePyObject_cb(PyObject *cb_user, int size, uchar cb_type, u
return (PyObject *)self;
}
-PyObject *Vector_CreatePyObject_alloc(float *vec, const int size, PyTypeObject *base_type)
+PyObject *Vector_CreatePyObject_alloc(float *vec, const int vec_num, PyTypeObject *base_type)
{
VectorObject *self;
- self = (VectorObject *)Vector_CreatePyObject_wrap(vec, size, base_type);
+ self = (VectorObject *)Vector_CreatePyObject_wrap(vec, vec_num, base_type);
if (self) {
self->flag &= ~BASE_MATH_FLAG_IS_WRAP;
}
diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h
index 422050c8742..3bc4e9d6b6f 100644
--- a/source/blender/python/mathutils/mathutils_Vector.h
+++ b/source/blender/python/mathutils/mathutils_Vector.h
@@ -14,12 +14,13 @@ extern PyTypeObject vector_Type;
typedef struct {
BASE_MATH_MEMBERS(vec);
- int size; /* vec size 2 or more */
+ /** Number of items in this vector (2 or more). */
+ int vec_num;
} VectorObject;
/*prototypes*/
PyObject *Vector_CreatePyObject(const float *vec,
- int size,
+ int vec_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT;
/**
* Create a vector that wraps existing memory.
@@ -27,7 +28,7 @@ PyObject *Vector_CreatePyObject(const float *vec,
* \param vec: Use this vector in-place.
*/
PyObject *Vector_CreatePyObject_wrap(float *vec,
- int size,
+ int vec_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1);
/**
@@ -35,13 +36,13 @@ PyObject *Vector_CreatePyObject_wrap(float *vec,
* see: #Mathutils_RegisterCallback
*/
PyObject *Vector_CreatePyObject_cb(PyObject *user,
- int size,
+ int vec_num,
unsigned char cb_type,
unsigned char subtype) ATTR_WARN_UNUSED_RESULT;
/**
* \param vec: Initialized vector value to use in-place, allocated with #PyMem_Malloc
*/
PyObject *Vector_CreatePyObject_alloc(float *vec,
- int size,
+ int vec_num,
PyTypeObject *base_type) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL(1);
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 84ba2ce4031..1e492574903 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -158,24 +158,30 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
PyObject *tuple;
PyObject *py_lines[4];
float lines[4][3], i1[3], i2[3];
- int len;
+ int ix_vec_num;
int result;
if (!PyArg_ParseTuple(args, "OOOO:intersect_line_line", UNPACK4_EX(&, py_lines, ))) {
return NULL;
}
- if ((((len = mathutils_array_parse(
+ if ((((ix_vec_num = mathutils_array_parse(
lines[0], 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[0], error_prefix)) != -1) &&
- (mathutils_array_parse(
- lines[1], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[1], error_prefix) !=
- -1) &&
- (mathutils_array_parse(
- lines[2], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[2], error_prefix) !=
- -1) &&
- (mathutils_array_parse(
- lines[3], len, len | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_lines[3], error_prefix) !=
- -1)) == 0) {
+ (mathutils_array_parse(lines[1],
+ ix_vec_num,
+ ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO,
+ py_lines[1],
+ error_prefix) != -1) &&
+ (mathutils_array_parse(lines[2],
+ ix_vec_num,
+ ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO,
+ py_lines[2],
+ error_prefix) != -1) &&
+ (mathutils_array_parse(lines[3],
+ ix_vec_num,
+ ix_vec_num | MU_ARRAY_SPILL | MU_ARRAY_ZERO,
+ py_lines[3],
+ error_prefix) != -1)) == 0) {
return NULL;
}
@@ -192,8 +198,9 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
}
tuple = PyTuple_New(2);
- PyTuple_SET_ITEMS(
- tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL));
+ PyTuple_SET_ITEMS(tuple,
+ Vector_CreatePyObject(i1, ix_vec_num, NULL),
+ Vector_CreatePyObject(i2, ix_vec_num, NULL));
return tuple;
}
@@ -764,14 +771,14 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
float pt[3], pt_out[3], line_a[3], line_b[3];
float lambda;
PyObject *ret;
- int size = 2;
+ int pt_num = 2;
if (!PyArg_ParseTuple(args, "OOO:intersect_point_line", &py_pt, &py_line_a, &py_line_b)) {
return NULL;
}
/* accept 2d verts */
- if ((((size = mathutils_array_parse(
+ if ((((pt_num = mathutils_array_parse(
pt, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_pt, error_prefix)) != -1) &&
(mathutils_array_parse(
line_a, 2, 3 | MU_ARRAY_SPILL | MU_ARRAY_ZERO, py_line_a, error_prefix) != -1) &&
@@ -784,7 +791,7 @@ static PyObject *M_Geometry_intersect_point_line(PyObject *UNUSED(self), PyObjec
lambda = closest_to_line_v3(pt_out, pt, line_a, line_b);
ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(pt_out, size, NULL), PyFloat_FromDouble(lambda));
+ PyTuple_SET_ITEMS(ret, Vector_CreatePyObject(pt_out, pt_num, NULL), PyFloat_FromDouble(lambda));
return ret;
}
diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c
index 0853c5dd3ea..e1282e90c48 100644
--- a/source/blender/python/mathutils/mathutils_noise.c
+++ b/source/blender/python/mathutils/mathutils_noise.c
@@ -305,23 +305,24 @@ static PyObject *M_Noise_random_unit_vector(PyObject *UNUSED(self), PyObject *ar
static const char *kwlist[] = {"size", NULL};
float vec[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float norm = 2.0f;
- int size = 3;
+ int vec_num = 3;
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_unit_vector", (char **)kwlist, &size)) {
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kw, "|$i:random_unit_vector", (char **)kwlist, &vec_num)) {
return NULL;
}
- if (size > 4 || size < 2) {
+ if (vec_num > 4 || vec_num < 2) {
PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
return NULL;
}
while (norm == 0.0f || norm > 1.0f) {
- rand_vn(vec, size);
- norm = normalize_vn(vec, size);
+ rand_vn(vec, vec_num);
+ norm = normalize_vn(vec, vec_num);
}
- return Vector_CreatePyObject(vec, size, NULL);
+ return Vector_CreatePyObject(vec, vec_num, NULL);
}
PyDoc_STRVAR(M_Noise_random_vector_doc,
@@ -337,22 +338,22 @@ static PyObject *M_Noise_random_vector(PyObject *UNUSED(self), PyObject *args, P
{
static const char *kwlist[] = {"size", NULL};
float *vec = NULL;
- int size = 3;
+ int vec_num = 3;
- if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_vector", (char **)kwlist, &size)) {
+ if (!PyArg_ParseTupleAndKeywords(args, kw, "|$i:random_vector", (char **)kwlist, &vec_num)) {
return NULL;
}
- if (size < 2) {
+ if (vec_num < 2) {
PyErr_SetString(PyExc_ValueError, "Vector(): invalid size");
return NULL;
}
- vec = PyMem_New(float, size);
+ vec = PyMem_New(float, vec_num);
- rand_vn(vec, size);
+ rand_vn(vec, vec_num);
- return Vector_CreatePyObject_alloc(vec, size, NULL);
+ return Vector_CreatePyObject_alloc(vec, vec_num, NULL);
}
PyDoc_STRVAR(M_Noise_seed_set_doc,
diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h
index 6d849757166..3a4a3e6dcb9 100644
--- a/source/blender/render/RE_bake.h
+++ b/source/blender/render/RE_bake.h
@@ -27,16 +27,16 @@ typedef struct BakeImage {
typedef struct BakeTargets {
/* All images of the object. */
BakeImage *images;
- int num_images;
+ int images_num;
/* Lookup table from Material number to BakeImage. */
int *material_to_image;
- int num_materials;
+ int materials_num;
/* Pixel buffer to bake to. */
float *result;
- int num_pixels;
- int num_channels;
+ int pixels_num;
+ int channels_num;
/* Baking to non-color data image. */
bool is_noncolor;
@@ -81,7 +81,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
BakePixel pixel_array_to[],
BakeHighPolyData highpoly[],
int tot_highpoly,
- size_t num_pixels,
+ size_t pixels_num,
bool is_custom_cage,
float cage_extrusion,
float max_ray_distance,
@@ -91,11 +91,11 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
void RE_bake_pixels_populate(struct Mesh *me,
struct BakePixel *pixel_array,
- size_t num_pixels,
+ size_t pixels_num,
const struct BakeTargets *targets,
const char *uv_layer);
-void RE_bake_mask_fill(const BakePixel pixel_array[], size_t num_pixels, char *mask);
+void RE_bake_mask_fill(const BakePixel pixel_array[], size_t pixels_num, char *mask);
void RE_bake_margin(struct ImBuf *ibuf,
char *mask,
@@ -105,7 +105,7 @@ void RE_bake_margin(struct ImBuf *ibuf,
char const *uv_layer);
void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
- size_t num_pixels,
+ size_t pixels_num,
int depth,
float result[],
struct Object *ob,
@@ -115,14 +115,14 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
* to a tangent space normal map for a given low poly mesh.
*/
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[],
- size_t num_pixels,
+ size_t pixels_num,
int depth,
float result[],
struct Mesh *me,
const eBakeNormalSwizzle normal_swizzle[3],
float mat[4][4]);
void RE_bake_normal_world_to_world(const BakePixel pixel_array[],
- size_t num_pixels,
+ size_t pixels_num,
int depth,
float result[],
const eBakeNormalSwizzle normal_swizzle[3]);
diff --git a/source/blender/render/RE_engine.h b/source/blender/render/RE_engine.h
index e8e47b1f646..e56e7b8d2e4 100644
--- a/source/blender/render/RE_engine.h
+++ b/source/blender/render/RE_engine.h
@@ -169,10 +169,10 @@ void RE_engine_free(RenderEngine *engine);
* x/y offsets are only used on a partial copy when dimensions don't match.
*/
void RE_layer_load_from_file(
- struct RenderLayer *layer, struct ReportList *reports, const char *filename, int x, int y);
+ struct RenderLayer *layer, struct ReportList *reports, const char *filepath, int x, int y);
void RE_result_load_from_file(struct RenderResult *result,
struct ReportList *reports,
- const char *filename);
+ const char *filepath);
struct RenderResult *RE_engine_begin_result(
RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname);
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index 596adafb2c9..69235fb6cb1 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -12,14 +12,14 @@
* The Bake API is fully implemented with Python rna functions.
* The operator expects/call a function:
*
- * `def bake(scene, object, pass_type, object_id, pixel_array, num_pixels, depth, result)`
+ * `def bake(scene, object, pass_type, object_id, pixel_array, pixels_num, depth, result)`
* - scene: current scene (Python object)
* - object: object to render (Python object)
* - pass_type: pass to render (string, e.g., "COMBINED", "AO", "NORMAL", ...)
* - object_id: index of object to bake (to use with the pixel_array)
* - pixel_array: list of primitive ids and barycentric coordinates to
* `bake(Python object, see bake_pixel)`.
- * - num_pixels: size of pixel_array, number of pixels to bake (int)
+ * - pixels_num: size of pixel_array, number of pixels to bake (int)
* - depth: depth of pixels to return (int, assuming always 4 now)
* - result: array to be populated by the engine (float array, PyLong_AsVoidPtr)
*
@@ -126,7 +126,7 @@ static void store_bake_pixel(void *handle, int x, int y, float u, float v)
pixel->seed = i;
}
-void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask)
+void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t pixels_num, char *mask)
{
size_t i;
if (!mask) {
@@ -134,7 +134,7 @@ void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, c
}
/* only extend to pixels outside the mask area */
- for (i = 0; i < num_pixels; i++) {
+ for (i = 0; i < pixels_num; i++) {
if (pixel_array[i].primitive_id != -1) {
mask[i] = FILTER_MASK_USED;
}
@@ -539,7 +539,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
BakePixel pixel_array_to[],
BakeHighPolyData highpoly[],
const int tot_highpoly,
- const size_t num_pixels,
+ const size_t pixels_num,
const bool is_custom_cage,
const float cage_extrusion,
const float max_ray_distance,
@@ -603,7 +603,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low,
}
}
- for (i = 0; i < num_pixels; i++) {
+ for (i = 0; i < pixels_num; i++) {
float co[3];
float dir[3];
TriTessFace *tri_low;
@@ -707,7 +707,7 @@ static void bake_differentials(BakeDataZSpan *bd,
void RE_bake_pixels_populate(Mesh *me,
BakePixel pixel_array[],
- const size_t num_pixels,
+ const size_t pixels_num,
const BakeTargets *targets,
const char *uv_layer)
{
@@ -726,15 +726,15 @@ void RE_bake_pixels_populate(Mesh *me,
BakeDataZSpan bd;
bd.pixel_array = pixel_array;
- bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->num_images, "bake zspan");
+ bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->images_num, "bake zspan");
/* initialize all pixel arrays so we know which ones are 'blank' */
- for (int i = 0; i < num_pixels; i++) {
+ for (int i = 0; i < pixels_num; i++) {
pixel_array[i].primitive_id = -1;
pixel_array[i].object_id = 0;
}
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height);
}
@@ -772,7 +772,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 (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
zbuf_free_span(&bd.zspan[i]);
}
@@ -823,7 +823,7 @@ static void normal_compress(float out[3],
}
void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[],
- const size_t num_pixels,
+ const size_t pixels_num,
const int depth,
float result[],
Mesh *me,
@@ -838,9 +838,9 @@ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[],
triangles = mesh_calc_tri_tessface(me, true, me_eval);
- BLI_assert(num_pixels >= 3);
+ BLI_assert(pixels_num >= 3);
- for (i = 0; i < num_pixels; i++) {
+ for (i = 0; i < pixels_num; i++) {
TriTessFace *triangle;
float tangents[3][3];
float normals[3][3];
@@ -948,7 +948,7 @@ void RE_bake_normal_world_to_tangent(const BakePixel pixel_array[],
}
void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
- const size_t num_pixels,
+ const size_t pixels_num,
const int depth,
float result[],
struct Object *ob,
@@ -959,7 +959,7 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
invert_m4_m4(iobmat, ob->obmat);
- for (i = 0; i < num_pixels; i++) {
+ for (i = 0; i < pixels_num; i++) {
size_t offset;
float nor[3];
@@ -980,14 +980,14 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[],
}
void RE_bake_normal_world_to_world(const BakePixel pixel_array[],
- const size_t num_pixels,
+ const size_t pixels_num,
const int depth,
float result[],
const eBakeNormalSwizzle normal_swizzle[3])
{
size_t i;
- for (i = 0; i < num_pixels; i++) {
+ for (i = 0; i < pixels_num; i++) {
size_t offset;
float nor[3];
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 3a7ac22dc1f..8a4b4c2a70d 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -827,14 +827,14 @@ bool RE_bake_engine(Render *re,
type->update(engine, re->main, engine->depsgraph);
}
- for (int i = 0; i < targets->num_images; i++) {
+ for (int i = 0; i < targets->images_num; i++) {
const BakeImage *image = targets->images + i;
engine->bake.pixels = pixel_array + image->offset;
- engine->bake.result = result + image->offset * targets->num_channels;
+ engine->bake.result = result + image->offset * targets->channels_num;
engine->bake.width = image->width;
engine->bake.height = image->height;
- engine->bake.depth = targets->num_channels;
+ engine->bake.depth = targets->channels_num;
engine->bake.object_id = object_id;
type->bake(
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index c573d4feed1..33d961c027d 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -1061,23 +1061,23 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
RayFace *face;
CCGElem **grid_data;
CCGKey key;
- int num_grids, grid_size /*, face_side */, num_faces;
+ int grids_num, grid_size /*, face_side */, faces_num;
int i;
- num_grids = hidm->getNumGrids(hidm);
+ grids_num = hidm->getNumGrids(hidm);
grid_size = hidm->getGridSize(hidm);
grid_data = hidm->getGridData(hidm);
hidm->getGridKey(hidm, &key);
/* face_side = (grid_size << 1) - 1; */ /* UNUSED */
- num_faces = num_grids * (grid_size - 1) * (grid_size - 1);
+ faces_num = grids_num * (grid_size - 1) * (grid_size - 1);
raytree = ao_data->raytree = RE_rayobject_create(
- bkr->raytrace_structure, num_faces, bkr->octree_resolution);
- face = ao_data->rayfaces = (RayFace *)MEM_callocN(num_faces * sizeof(RayFace),
+ bkr->raytrace_structure, faces_num, bkr->octree_resolution);
+ face = ao_data->rayfaces = (RayFace *)MEM_callocN(faces_num * sizeof(RayFace),
"ObjectRen faces");
- for (i = 0; i < num_grids; i++) {
+ for (i = 0; i < grids_num; i++) {
int x, y;
for (x = 0; x < grid_size - 1; x++) {
for (y = 0; y < grid_size - 1; y++) {
diff --git a/source/blender/render/intern/pipeline.c b/source/blender/render/intern/pipeline.c
index a6c2e9eb194..cf400bdfc77 100644
--- a/source/blender/render/intern/pipeline.c
+++ b/source/blender/render/intern/pipeline.c
@@ -2480,10 +2480,10 @@ bool RE_ReadRenderResult(Scene *scene, Scene *scenode)
}
void RE_layer_load_from_file(
- RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
+ RenderLayer *layer, ReportList *reports, const char *filepath, int x, int y)
{
/* OCIO_TODO: assume layer was saved in default color space */
- ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL);
+ ImBuf *ibuf = IMB_loadiffname(filepath, IB_rect, NULL);
RenderPass *rpass = NULL;
/* multiview: since the API takes no 'view', we use the first combined pass found */
@@ -2498,7 +2498,7 @@ void RE_layer_load_from_file(
RPT_ERROR,
"%s: no Combined pass found in the render layer '%s'",
__func__,
- filename);
+ filepath);
}
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
@@ -2527,7 +2527,7 @@ void RE_layer_load_from_file(
}
else {
BKE_reportf(
- reports, RPT_ERROR, "%s: failed to allocate clip buffer '%s'", __func__, filename);
+ reports, RPT_ERROR, "%s: failed to allocate clip buffer '%s'", __func__, filepath);
}
}
else {
@@ -2535,21 +2535,21 @@ void RE_layer_load_from_file(
RPT_ERROR,
"%s: incorrect dimensions for partial copy '%s'",
__func__,
- filename);
+ filepath);
}
}
IMB_freeImBuf(ibuf);
}
else {
- BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filename);
+ BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath);
}
}
-void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filename)
+void RE_result_load_from_file(RenderResult *result, ReportList *reports, const char *filepath)
{
- if (!render_result_exr_file_read_path(result, NULL, filename)) {
- BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filename);
+ if (!render_result_exr_file_read_path(result, NULL, filepath)) {
+ BKE_reportf(reports, RPT_ERROR, "%s: failed to load '%s'", __func__, filepath);
return;
}
}
diff --git a/source/blender/render/intern/render_result.c b/source/blender/render/intern/render_result.c
index ea7fa961f0d..9f4aa642773 100644
--- a/source/blender/render/intern/render_result.c
+++ b/source/blender/render/intern/render_result.c
@@ -402,7 +402,7 @@ RenderResult *render_result_new(Render *re,
render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA", false);
}
- /* NOTE: this has to be in sync with `scene.c`. */
+ /* NOTE: this has to be in sync with `scene.cc`. */
rl->layflag = SCE_LAY_FLAG_DEFAULT;
rl->passflag = SCE_PASS_COMBINED;
diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc
index adc11cd925e..d01c0dbea71 100644
--- a/source/blender/render/intern/texture_margin.cc
+++ b/source/blender/render/intern/texture_margin.cc
@@ -331,7 +331,7 @@ class TextureMarginMap {
float destx, desty;
int foundpoly;
- float mindist = -1.f;
+ float mindist = -1.0f;
/* Loop over all adjacent polygons and determine which edge is closest.
* This could be optimized by only inspecting neighbors which are on the edge of an island.
@@ -356,7 +356,7 @@ class TextureMarginMap {
}
}
- return mindist >= 0.f;
+ return mindist >= 0.0f;
}
/**
diff --git a/source/blender/sequencer/SEQ_animation.h b/source/blender/sequencer/SEQ_animation.h
index 455e77fb4a3..f2c66393b65 100644
--- a/source/blender/sequencer/SEQ_animation.h
+++ b/source/blender/sequencer/SEQ_animation.h
@@ -19,6 +19,18 @@ struct Sequence;
void SEQ_free_animdata(struct Scene *scene, struct Sequence *seq);
void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs);
struct GSet *SEQ_fcurves_by_strip_get(const struct Sequence *seq, struct ListBase *fcurve_base);
+/**
+ * Move all `F-curves` from `scene` to `list`.
+ */
+void SEQ_animation_backup_original(struct Scene *scene, struct ListBase *list);
+/**
+ * Move all `F-curves` from `list` to `scene`.
+ */
+void SEQ_animation_restore_original(struct Scene *scene, struct ListBase *list);
+/**
+ * Duplicate `F-curves` used by `seq` from `list` to `scene`.
+ */
+void SEQ_animation_duplicate(struct Scene *scene, struct Sequence *seq, struct ListBase *list);
#ifdef __cplusplus
}
diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c
index 47453ceda2b..27f7316e042 100644
--- a/source/blender/sequencer/intern/animation.c
+++ b/source/blender/sequencer/intern/animation.c
@@ -104,3 +104,32 @@ void SEQ_free_animdata(Scene *scene, Sequence *seq)
GSET_FOREACH_END();
BLI_gset_free(fcurves, NULL);
}
+
+void SEQ_animation_backup_original(Scene *scene, ListBase *list)
+{
+ if (scene->adt == NULL || scene->adt->action == NULL ||
+ BLI_listbase_is_empty(&scene->adt->action->curves)) {
+ return;
+ }
+
+ BLI_movelisttolist(list, &scene->adt->action->curves);
+}
+
+void SEQ_animation_restore_original(Scene *scene, ListBase *list)
+{
+ if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) {
+ return;
+ }
+
+ BLI_movelisttolist(&scene->adt->action->curves, list);
+}
+
+void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list)
+{
+ GSet *fcurves = SEQ_fcurves_by_strip_get(seq, list);
+ GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) {
+ FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
+ BLI_addtail(&scene->adt->action->curves, fcu_cpy);
+ }
+ GSET_FOREACH_END();
+}
diff --git a/source/blender/sequencer/intern/disk_cache.c b/source/blender/sequencer/intern/disk_cache.c
index 9216383d274..0fdaef61b65 100644
--- a/source/blender/sequencer/intern/disk_cache.c
+++ b/source/blender/sequencer/intern/disk_cache.c
@@ -160,10 +160,11 @@ static DiskCacheFile *seq_disk_cache_add_file_to_list(SeqDiskCache *disk_cache,
static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path)
{
struct direntry *filelist, *fl;
- uint nbr, i;
+ uint i;
disk_cache->size_total = 0;
- i = nbr = BLI_filelist_dir_contents(path, &filelist);
+ const int filelist_num = BLI_filelist_dir_contents(path, &filelist);
+ i = filelist_num;
fl = filelist;
while (i--) {
/* Don't follow links. */
@@ -194,7 +195,7 @@ static void seq_disk_cache_get_files(SeqDiskCache *disk_cache, char *path)
}
fl++;
}
- BLI_filelist_free(filelist, nbr);
+ BLI_filelist_free(filelist, filelist_num);
}
static DiskCacheFile *seq_disk_cache_get_oldest_file(SeqDiskCache *disk_cache)
diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c
index 8f7088b0c4b..a4ab7671eb0 100644
--- a/source/blender/sequencer/intern/effects.c
+++ b/source/blender/sequencer/intern/effects.c
@@ -1681,7 +1681,7 @@ static void do_wipe_effect_byte(Sequence *seq,
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
- float check = check_zone(&wipezone, x, y, seq, fac);
+ float check = check_zone(&wipezone, j, i, seq, fac);
if (check) {
if (cp1) {
float rt1[4], rt2[4], tempc[4];
@@ -1742,7 +1742,7 @@ static void do_wipe_effect_float(
for (int i = 0; i < y; i++) {
for (int j = 0; j < x; j++) {
- float check = check_zone(&wipezone, x, y, seq, fac);
+ float check = check_zone(&wipezone, j, i, seq, fac);
if (check) {
if (rt1) {
rt[0] = rt1[0] * check + rt2[0] * (1 - check);
diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c
index 60f3f35314e..2f76b6240cf 100644
--- a/source/blender/sequencer/intern/strip_edit.c
+++ b/source/blender/sequencer/intern/strip_edit.c
@@ -457,11 +457,18 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
return NULL;
}
- /* Move strips in collection from seqbase to new ListBase. */
+ /* Store `F-curves`, so original ones aren't renamed. */
+ ListBase fcurves_original_backup = {NULL, NULL};
+ SEQ_animation_backup_original(scene, &fcurves_original_backup);
+
ListBase left_strips = {NULL, NULL};
SEQ_ITERATOR_FOREACH (seq, collection) {
+ /* Move strips in collection from seqbase to new ListBase. */
BLI_remlink(seqbase, seq);
BLI_addtail(&left_strips, seq);
+
+ /* Duplicate curves from backup, so they can be renamed along with split strips. */
+ SEQ_animation_duplicate(scene, seq, &fcurves_original_backup);
}
SEQ_collection_free(collection);
@@ -511,6 +518,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain,
SEQ_ensure_unique_name(seq_rename, scene);
}
+ SEQ_animation_restore_original(scene, &fcurves_original_backup);
+
return return_seq;
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 7959c3d6f0b..0864627ebe3 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -740,14 +740,33 @@ bool WM_operator_last_properties_store(struct wmOperator *op);
/* wm_operator_props.c */
void WM_operator_properties_confirm_or_exec(struct wmOperatorType *ot);
+
+/** Flags for #WM_operator_properties_filesel. */
+typedef enum eFileSel_Flag {
+ WM_FILESEL_RELPATH = 1 << 0,
+ WM_FILESEL_DIRECTORY = 1 << 1,
+ WM_FILESEL_FILENAME = 1 << 2,
+ WM_FILESEL_FILEPATH = 1 << 3,
+ WM_FILESEL_FILES = 1 << 4,
+ /** Show the properties sidebar by default. */
+ WM_FILESEL_SHOW_PROPS = 1 << 5,
+} eFileSel_Flag;
+ENUM_OPERATORS(eFileSel_Flag, WM_FILESEL_SHOW_PROPS)
+
+/** Action for #WM_operator_properties_filesel. */
+typedef enum eFileSel_Action {
+ FILE_OPENFILE = 0,
+ FILE_SAVE = 1,
+} eFileSel_Action;
+
/**
* Default properties for file-select.
*/
void WM_operator_properties_filesel(struct wmOperatorType *ot,
int filter,
short type,
- short action,
- short flag,
+ eFileSel_Action action,
+ eFileSel_Flag flag,
short display,
short sort);
/**
@@ -841,16 +860,6 @@ void WM_operator_properties_checker_interval_from_op(struct wmOperator *op,
bool WM_operator_properties_checker_interval_test(const struct CheckerIntervalParams *op_params,
int depth);
-/* flags for WM_operator_properties_filesel */
-#define WM_FILESEL_RELPATH (1 << 0)
-
-#define WM_FILESEL_DIRECTORY (1 << 1)
-#define WM_FILESEL_FILENAME (1 << 2)
-#define WM_FILESEL_FILEPATH (1 << 3)
-#define WM_FILESEL_FILES (1 << 4)
-/* Show the properties sidebar by default. */
-#define WM_FILESEL_SHOW_PROPS (1 << 5)
-
/**
* Operator as a Python command (resulting string must be freed).
*
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 790b08437bd..60ae4eccbbe 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1063,7 +1063,7 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat,
if (hud_status != NOP) {
if (hud_status == SET) {
ScrArea *area = CTX_wm_area(C);
- if (area) {
+ if (area && ((area->flag & AREA_FLAG_OFFSCREEN) == 0)) {
ED_area_type_hud_ensure(C, area);
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 04ce7bcb520..caa3a493349 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -867,7 +867,7 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports)
RPT_WARNING,
"Proxies have been removed from Blender (%d proxies were automatically converted "
"to library overrides, %d proxies could not be converted and were cleared). "
- "Please also consider re-saving any library .blend file with the newest Blender version.",
+ "Please also consider re-saving any library .blend file with the newest Blender version",
bf_reports->count.proxies_to_lib_overrides_success,
bf_reports->count.proxies_to_lib_overrides_failures);
}
@@ -1999,20 +1999,20 @@ void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer *UNUSED(wt))
void wm_autosave_delete(void)
{
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
- wm_autosave_location(filename);
+ wm_autosave_location(filepath);
- if (BLI_exists(filename)) {
+ if (BLI_exists(filepath)) {
char str[FILE_MAX];
BLI_join_dirfile(str, sizeof(str), BKE_tempdir_base(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
if (U.uiflag & USER_GLOBALUNDO) {
- BLI_delete(filename, false, false);
+ BLI_delete(filepath, false, false);
}
else {
- BLI_rename(filename, str);
+ BLI_rename(filepath, str);
}
}
}
@@ -2959,10 +2959,10 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
- wm_autosave_location(filename);
- RNA_string_set(op->ptr, "filepath", filename);
+ wm_autosave_location(filepath);
+ RNA_string_set(op->ptr, "filepath", filepath);
wm_open_init_use_scripts(op, true);
WM_event_add_fileselect(C, op);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 6a9776c6933..8d6741dcfb6 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -440,19 +440,19 @@ void WM_exit_ex(bContext *C, const bool do_python)
if (undo_memfile != NULL) {
/* save the undo state as quit.blend */
Main *bmain = CTX_data_main(C);
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
bool has_edited;
const int fileflags = G.fileflags & ~G_FILE_COMPRESS;
- BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_base(), BLENDER_QUIT_FILE);
+ BLI_join_dirfile(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE);
has_edited = ED_editors_flush_edits(bmain);
if ((has_edited &&
BLO_write_file(
- bmain, filename, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) ||
- (BLO_memfile_write_file(undo_memfile, filename))) {
- printf("Saved session recovery to '%s'\n", filename);
+ bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) ||
+ (BLO_memfile_write_file(undo_memfile, filepath))) {
+ printf("Saved session recovery to '%s'\n", filepath);
}
}
}
diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c
index dacc17c2c1e..c048b64426a 100644
--- a/source/blender/windowmanager/intern/wm_operator_props.c
+++ b/source/blender/windowmanager/intern/wm_operator_props.c
@@ -58,12 +58,12 @@ static const EnumPropertyItem *wm_operator_properties_filesel_sort_items_itemf(
}
void WM_operator_properties_filesel(wmOperatorType *ot,
- int filter,
- short type,
- short action,
- short flag,
- short display,
- short sort)
+ const int filter,
+ const short type,
+ const eFileSel_Action action,
+ const eFileSel_Flag flag,
+ const short display,
+ const short sort)
{
PropertyRNA *prop;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index c706e99b592..b45c638d7b9 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1991,7 +1991,7 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
{
ot->name = "Toggle Window Fullscreen";
ot->idname = "WM_OT_window_fullscreen_toggle";
- ot->description = "Toggle the current window fullscreen";
+ ot->description = "Toggle the current window full-screen";
ot->exec = wm_window_fullscreen_toggle_exec;
ot->poll = WM_operator_winactive;
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index 0d131ad207e..e1f5bb6377d 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -828,7 +828,7 @@ static int arg_handle_log_show_timestamp_set(int UNUSED(argc),
}
static const char arg_handle_log_file_set_doc[] =
- "<filename>\n"
+ "<filepath>\n"
"\tSet a file to output the log to.";
static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(data))
{
@@ -1432,7 +1432,7 @@ static const char arg_handle_image_type_set_doc[] =
"\t'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'IRIZ' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP'\n"
"\n"
"\tFormats that can be compiled into Blender, not available on all systems:\n"
- "\t'HDR' 'TIFF' 'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'MPEG' 'CINEON' 'DPX' 'DDS' 'JP2'";
+ "\t'HDR' 'TIFF' 'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'MPEG' 'CINEON' 'DPX' 'DDS' 'JP2' 'WEBP'";
static int arg_handle_image_type_set(int argc, const char **argv, void *data)
{
bContext *C = data;
@@ -1752,7 +1752,7 @@ static int arg_handle_frame_skip_set(int argc, const char **argv, void *data)
}
static const char arg_handle_python_file_run_doc[] =
- "<filename>\n"
+ "<filepath>\n"
"\tRun the given Python script file.";
static int arg_handle_python_file_run(int argc, const char **argv, void *data)
{
@@ -1762,12 +1762,12 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data)
/* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
if (argc > 1) {
/* Make the path absolute because its needed for relative linked blends to be found */
- char filename[FILE_MAX];
- BLI_strncpy(filename, argv[1], sizeof(filename));
- BLI_path_abs_from_cwd(filename, sizeof(filename));
+ char filepath[FILE_MAX];
+ BLI_strncpy(filepath, argv[1], sizeof(filepath));
+ BLI_path_abs_from_cwd(filepath, sizeof(filepath));
bool ok;
- BPY_CTX_SETUP(ok = BPY_run_filepath(C, filename, NULL));
+ BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, NULL));
if (!ok && app_state.exit_code_on_error.python) {
printf("\nError: script failed, file: '%s', exiting.\n", argv[1]);
BPY_python_end();
@@ -1952,22 +1952,22 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data)
bool success;
/* Make the path absolute because its needed for relative linked blends to be found */
- char filename[FILE_MAX];
+ char filepath[FILE_MAX];
/* NOTE: we could skip these, but so far we always tried to load these files. */
if (argv[0][0] == '-') {
fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
}
- BLI_strncpy(filename, argv[0], sizeof(filename));
- BLI_path_slash_native(filename);
- BLI_path_abs_from_cwd(filename, sizeof(filename));
- BLI_path_normalize(NULL, filename);
+ BLI_strncpy(filepath, argv[0], sizeof(filepath));
+ BLI_path_slash_native(filepath);
+ BLI_path_abs_from_cwd(filepath, sizeof(filepath));
+ BLI_path_normalize(NULL, filepath);
/* load the file */
BKE_reports_init(&reports, RPT_PRINT);
- WM_file_autoexec_init(filename);
- success = WM_file_read(C, filename, &reports);
+ WM_file_autoexec_init(filepath);
+ success = WM_file_read(C, filepath, &reports);
BKE_reports_clear(&reports);
if (success) {
@@ -1988,16 +1988,16 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data)
return -1;
}
- if (BLO_has_bfile_extension(filename)) {
+ if (BLO_has_bfile_extension(filepath)) {
/* Just pretend a file was loaded, so the user can press Save and it'll
- * save at the filename from the CLI. */
- STRNCPY(G_MAIN->filepath, filename);
- printf("... opened default scene instead; saving will write to: %s\n", filename);
+ * save at the filepath from the CLI. */
+ STRNCPY(G_MAIN->filepath, filepath);
+ printf("... opened default scene instead; saving will write to: %s\n", filepath);
}
else {
printf(
"Error: argument has no '.blend' file extension, not using as new file, exiting! %s\n",
- filename);
+ filepath);
G.is_break = true;
WM_exit(C);
}