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:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenfont/intern/blf.c4
-rw-r--r--source/blender/blenfont/intern/blf_font.c2
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h6
-rw-r--r--source/blender/blenkernel/BKE_colortools.h2
-rw-r--r--source/blender/blenkernel/BKE_curveprofile.h2
-rw-r--r--source/blender/blenkernel/BKE_image.h29
-rw-r--r--source/blender/blenkernel/BKE_lib_override.h2
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h3
-rw-r--r--source/blender/blenkernel/BKE_ocean.h6
-rw-r--r--source/blender/blenkernel/BKE_paint.h25
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_persistent_data_handle.hh22
-rw-r--r--source/blender/blenkernel/BKE_screen.h2
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h4
-rw-r--r--source/blender/blenkernel/BKE_simulation.h1
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c2
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/armature_update.c2
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c20
-rw-r--r--source/blender/blenkernel/intern/cachefile.c2
-rw-r--r--source/blender/blenkernel/intern/camera.c124
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collection.c31
-rw-r--r--source/blender/blenkernel/intern/colorband.c21
-rw-r--r--source/blender/blenkernel/intern/colortools.c47
-rw-r--r--source/blender/blenkernel/intern/constraint.c22
-rw-r--r--source/blender/blenkernel/intern/context.c97
-rw-r--r--source/blender/blenkernel/intern/curve.c218
-rw-r--r--source/blender/blenkernel/intern/curve_bevel.c272
-rw-r--r--source/blender/blenkernel/intern/curveprofile.c29
-rw-r--r--source/blender/blenkernel/intern/customdata.c29
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c10
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c29
-rw-r--r--source/blender/blenkernel/intern/deform.c83
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c10
-rw-r--r--source/blender/blenkernel/intern/editmesh_cache.c9
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve.c4
-rw-r--r--source/blender/blenkernel/intern/fcurve_driver.c395
-rw-r--r--source/blender/blenkernel/intern/fluid.c115
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c71
-rw-r--r--source/blender/blenkernel/intern/font.c69
-rw-r--r--source/blender/blenkernel/intern/gpencil.c68
-rw-r--r--source/blender/blenkernel/intern/gpencil_curve.c2
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.c56
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c5
-rw-r--r--source/blender/blenkernel/intern/hair.c4
-rw-r--r--source/blender/blenkernel/intern/icons.c19
-rw-r--r--source/blender/blenkernel/intern/idprop.c25
-rw-r--r--source/blender/blenkernel/intern/idtype.c5
-rw-r--r--source/blender/blenkernel/intern/image.c280
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c774
-rw-r--r--source/blender/blenkernel/intern/ipo.c14
-rw-r--r--source/blender/blenkernel/intern/lattice.c10
-rw-r--r--source/blender/blenkernel/intern/layer.c27
-rw-r--r--source/blender/blenkernel/intern/lib_id.c15
-rw-r--r--source/blender/blenkernel/intern/lib_override.c7
-rw-r--r--source/blender/blenkernel/intern/lib_query.c8
-rw-r--r--source/blender/blenkernel/intern/light.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c137
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c5
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c66
-rw-r--r--source/blender/blenkernel/intern/material.c44
-rw-r--r--source/blender/blenkernel/intern/mball.c5
-rw-r--r--source/blender/blenkernel/intern/mesh.c56
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c34
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c7
-rw-r--r--source/blender/blenkernel/intern/mesh_merge.c18
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c10
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c33
-rw-r--r--source/blender/blenkernel/intern/modifier.c23
-rw-r--r--source/blender/blenkernel/intern/movieclip.c90
-rw-r--r--source/blender/blenkernel/intern/multires.c15
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_apply_base.c2
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c103
-rw-r--r--source/blender/blenkernel/intern/node.c58
-rw-r--r--source/blender/blenkernel/intern/object.c90
-rw-r--r--source/blender/blenkernel/intern/object_deform.c2
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c99
-rw-r--r--source/blender/blenkernel/intern/ocean.c23
-rw-r--r--source/blender/blenkernel/intern/packedFile.c9
-rw-r--r--source/blender/blenkernel/intern/paint.c41
-rw-r--r--source/blender/blenkernel/intern/particle.c196
-rw-r--r--source/blender/blenkernel/intern/particle_child.c9
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c12
-rw-r--r--source/blender/blenkernel/intern/particle_system.c331
-rw-r--r--source/blender/blenkernel/intern/pbvh.c88
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c14
-rw-r--r--source/blender/blenkernel/intern/pointcache.c31
-rw-r--r--source/blender/blenkernel/intern/pointcloud.c4
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c127
-rw-r--r--source/blender/blenkernel/intern/scene.c170
-rw-r--r--source/blender/blenkernel/intern/seqcache.c23
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c7
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c8
-rw-r--r--source/blender/blenkernel/intern/sequencer.c182
-rw-r--r--source/blender/blenkernel/intern/shader_fx.c5
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c35
-rw-r--r--source/blender/blenkernel/intern/simulation.cc19
-rw-r--r--source/blender/blenkernel/intern/softbody.c17
-rw-r--r--source/blender/blenkernel/intern/sound.c10
-rw-r--r--source/blender/blenkernel/intern/studiolight.c49
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg.c4
-rw-r--r--source/blender/blenkernel/intern/subdiv_displacement_multires.c9
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c2
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c6
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c34
-rw-r--r--source/blender/blenkernel/intern/text.c37
-rw-r--r--source/blender/blenkernel/intern/texture.c4
-rw-r--r--source/blender/blenkernel/intern/tracking.c181
-rw-r--r--source/blender/blenkernel/intern/tracking_solver.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c56
-rw-r--r--source/blender/blenkernel/intern/undo_system.c5
-rw-r--r--source/blender/blenkernel/intern/unit.c10
-rw-r--r--source/blender/blenkernel/intern/volume.cc25
-rw-r--r--source/blender/blenkernel/intern/volume_render.cc5
-rw-r--r--source/blender/blenkernel/intern/workspace.c12
-rw-r--r--source/blender/blenlib/BLI_dial_2d.h4
-rw-r--r--source/blender/blenlib/BLI_dot_export.hh78
-rw-r--r--source/blender/blenlib/BLI_float3.hh23
-rw-r--r--source/blender/blenlib/BLI_float4x4.hh16
-rw-r--r--source/blender/blenlib/BLI_multi_value_map.hh131
-rw-r--r--source/blender/blenlib/BLI_rand.hh38
-rw-r--r--source/blender/blenlib/BLI_resource_collector.hh6
-rw-r--r--source/blender/blenlib/BLI_span.hh71
-rw-r--r--source/blender/blenlib/BLI_utildefines.h37
-rw-r--r--source/blender/blenlib/BLI_vector.hh2
-rw-r--r--source/blender/blenlib/BLI_vector_adaptor.hh102
-rw-r--r--source/blender/blenlib/CMakeLists.txt27
-rw-r--r--source/blender/blenlib/intern/BLI_args.c8
-rw-r--r--source/blender/blenlib/intern/BLI_dial_2d.c2
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c42
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c90
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c2
-rw-r--r--source/blender/blenlib/intern/BLI_memiter.c16
-rw-r--r--source/blender/blenlib/intern/DLRB_tree.c8
-rw-r--r--source/blender/blenlib/intern/array_store.c26
-rw-r--r--source/blender/blenlib/intern/array_utils.c2
-rw-r--r--source/blender/blenlib/intern/bitmap_draw_2d.c28
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c8
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c17
-rw-r--r--source/blender/blenlib/intern/delaunay_2d.c57
-rw-r--r--source/blender/blenlib/intern/dot_export.cc38
-rw-r--r--source/blender/blenlib/intern/easing.c35
-rw-r--r--source/blender/blenlib/intern/edgehash.c14
-rw-r--r--source/blender/blenlib/intern/fileops.c15
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c7
-rw-r--r--source/blender/blenlib/intern/listbase.c5
-rw-r--r--source/blender/blenlib/intern/math_color.c10
-rw-r--r--source/blender/blenlib/intern/math_geom.c592
-rw-r--r--source/blender/blenlib/intern/math_interp.c2
-rw-r--r--source/blender/blenlib/intern/math_rotation.c30
-rw-r--r--source/blender/blenlib/intern/math_vector.c18
-rw-r--r--source/blender/blenlib/intern/path_util.c73
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c14
-rw-r--r--source/blender/blenlib/intern/polyfill_2d_beautify.c15
-rw-r--r--source/blender/blenlib/intern/quadric.c10
-rw-r--r--source/blender/blenlib/intern/rct.c194
-rw-r--r--source/blender/blenlib/intern/scanfill.c96
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c5
-rw-r--r--source/blender/blenlib/intern/smallhash.c7
-rw-r--r--source/blender/blenlib/intern/sort_utils.c42
-rw-r--r--source/blender/blenlib/intern/storage.c4
-rw-r--r--source/blender/blenlib/intern/string.c32
-rw-r--r--source/blender/blenlib/intern/string_utf8.c8
-rw-r--r--source/blender/blenlib/intern/string_utils.c2
-rw-r--r--source/blender/blenlib/intern/threads.cc4
-rw-r--r--source/blender/blenlib/intern/voronoi_2d.c6
-rw-r--r--source/blender/blenlib/tests/BLI_array_test.cc176
-rw-r--r--source/blender/blenlib/tests/BLI_disjoint_set_test.cc36
-rw-r--r--source/blender/blenlib/tests/BLI_edgehash_test.cc408
-rw-r--r--source/blender/blenlib/tests/BLI_index_mask_test.cc43
-rw-r--r--source/blender/blenlib/tests/BLI_index_range_test.cc143
-rw-r--r--source/blender/blenlib/tests/BLI_linear_allocator_test.cc118
-rw-r--r--source/blender/blenlib/tests/BLI_map_test.cc590
-rw-r--r--source/blender/blenlib/tests/BLI_math_base_safe_test.cc37
-rw-r--r--source/blender/blenlib/tests/BLI_memory_utils_test.cc159
-rw-r--r--source/blender/blenlib/tests/BLI_multi_value_map_test.cc109
-rw-r--r--source/blender/blenlib/tests/BLI_set_test.cc565
-rw-r--r--source/blender/blenlib/tests/BLI_span_test.cc311
-rw-r--r--source/blender/blenlib/tests/BLI_stack_cxx_test.cc188
-rw-r--r--source/blender/blenlib/tests/BLI_string_ref_test.cc277
-rw-r--r--source/blender/blenlib/tests/BLI_vector_set_test.cc164
-rw-r--r--source/blender/blenlib/tests/BLI_vector_test.cc639
-rw-r--r--source/blender/blenloader/intern/readblenentry.c45
-rw-r--r--source/blender/blenloader/intern/readfile.c116
-rw-r--r--source/blender/blenloader/intern/versioning_250.c9
-rw-r--r--source/blender/blenloader/intern/versioning_260.c5
-rw-r--r--source/blender/blenloader/intern/versioning_270.c10
-rw-r--r--source/blender/blenloader/intern/versioning_280.c17
-rw-r--r--source/blender/blenloader/intern/versioning_290.c36
-rw-r--r--source/blender/blenloader/intern/versioning_cycles.c2
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c6
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c3
-rw-r--r--source/blender/blenloader/intern/versioning_userdef.c2
-rw-r--r--source/blender/blenloader/intern/writefile.c19
-rw-r--r--source/blender/blentranslation/intern/blt_translation.c24
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_query.c9
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c275
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c5
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect_edges.c2
-rw-r--r--source/blender/compositor/intern/COM_CompositorContext.cpp5
-rw-r--r--source/blender/compositor/intern/COM_Converter.cpp10
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.cpp7
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cpp51
-rw-r--r--source/blender/compositor/nodes/COM_TimeNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_AntiAliasOperation.cpp6
-rw-r--r--source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_CurveBaseOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_DenoiseOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_DisplaceOperation.cpp13
-rw-r--r--source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp33
-rw-r--r--source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp46
-rw-r--r--source/blender/compositor/operations/COM_GlareBaseOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_GlareGhostOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.cpp33
-rw-r--r--source/blender/compositor/operations/COM_InpaintOperation.h4
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cpp15
-rw-r--r--source/blender/compositor/operations/COM_OutputFileOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_VectorBlurOperation.cpp5
-rw-r--r--source/blender/compositor/operations/COM_ViewerOperation.cpp5
-rw-r--r--source/blender/datatoc/datatoc_icon.c2
-rw-r--r--source/blender/depsgraph/CMakeLists.txt10
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc132
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.cc14
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_rna.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_transitive.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.cc132
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline.h77
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.cc49
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_compositor.h47
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.cc154
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_from_ids.h62
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.cc49
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_render.h41
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.cc48
-rw-r--r--source/blender/depsgraph/intern/builder/pipeline_view_layer.h41
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc357
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc261
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc19
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc10
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc5
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc9
-rw-r--r--source/blender/depsgraph/intern/node/deg_node.cc7
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_component.cc8
-rw-r--r--source/blender/draw/CMakeLists.txt24
-rw-r--r--source/blender/draw/engines/eevee/eevee_depth_of_field.c38
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c9
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c40
-rw-r--r--source/blender/draw/engines/eevee/eevee_lookdev.c158
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut_gen.c30
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c126
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c18
-rw-r--r--source/blender/draw/engines/eevee/eevee_motion_blur.c65
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c23
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h17
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_sampling.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c28
-rw-r--r--source/blender/draw/engines/eevee/eevee_shaders.c465
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c27
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows_cascade.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c44
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c119
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/background_vert.glsl18
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl877
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_lib.glsl181
-rw-r--r--source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl (renamed from source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl)42
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl65
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl51
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl12
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl38
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl9
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl29
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl57
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl20
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl95
-rw-r--r--source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl (renamed from source/blender/draw/engines/eevee/shaders/default_world_frag.glsl)43
-rw-r--r--source/blender/draw/engines/eevee/shaders/ltc_lib.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_frag.glsl14
-rw-r--r--source/blender/draw/engines/eevee/shaders/prepass_vert.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl12
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl36
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_frag.glsl89
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_geom.glsl46
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_lib.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/surface_vert.glsl (renamed from source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl)33
-rw-r--r--source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl4
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl2
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl8
-rw-r--r--source/blender/draw/engines/external/external_engine.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_antialiasing.c2
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c11
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_data.c9
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c6
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_render.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_antialiasing.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_armature.c23
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_text.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_engine.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_extra.c21
-rw-r--r--source/blender/draw/engines/overlay/overlay_image.c22
-rw-r--r--source/blender/draw/engines/overlay/overlay_motion_path.c4
-rw-r--r--source/blender/draw/engines/overlay/overlay_outline.c2
-rw-r--r--source/blender/draw/engines/overlay/overlay_paint.c10
-rw-r--r--source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl13
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_frag.glsl2
-rw-r--r--source/blender/draw/engines/overlay/shaders/grid_vert.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl4
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl28
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl10
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl2
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl10
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_antialiasing.c103
-rw-r--r--source/blender/draw/engines/workbench/workbench_effect_dof.c2
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c6
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c8
-rw-r--r--source/blender/draw/engines/workbench/workbench_shader.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_shadow.c4
-rw-r--r--source/blender/draw/engines/workbench/workbench_volume.c17
-rw-r--r--source/blender/draw/intern/DRW_render.h17
-rw-r--r--source/blender/draw/intern/draw_cache.c118
-rw-r--r--source/blender/draw/intern/draw_cache_extract_mesh.c31
-rw-r--r--source/blender/draw/intern/draw_cache_impl_gpencil.c5
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c25
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c5
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c20
-rw-r--r--source/blender/draw/intern/draw_cache_impl_pointcloud.c7
-rw-r--r--source/blender/draw/intern/draw_common.c6
-rw-r--r--source/blender/draw/intern/draw_common.h18
-rw-r--r--source/blender/draw/intern/draw_fluid.c (renamed from source/blender/gpu/intern/gpu_draw_smoke.c)40
-rw-r--r--source/blender/draw/intern/draw_hair.c2
-rw-r--r--source/blender/draw/intern/draw_manager.c11
-rw-r--r--source/blender/draw/intern/draw_manager_data.c78
-rw-r--r--source/blender/draw/intern/draw_manager_exec.c17
-rw-r--r--source/blender/draw/intern/draw_manager_shader.c12
-rw-r--r--source/blender/draw/intern/draw_select_buffer.c2
-rw-r--r--source/blender/draw/intern/draw_view.c5
-rw-r--r--source/blender/draw/intern/shaders/common_hair_lib.glsl22
-rw-r--r--source/blender/draw/intern/shaders/common_math_geom_lib.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_pointcloud_lib.glsl2
-rw-r--r--source/blender/draw/intern/shaders/common_view_lib.glsl107
-rw-r--r--source/blender/editors/animation/anim_filter.c2
-rw-r--r--source/blender/editors/armature/pose_slide.c12
-rw-r--r--source/blender/editors/curve/editcurve.c11
-rw-r--r--source/blender/editors/curve/editcurve_add.c8
-rw-r--r--source/blender/editors/curve/editfont.c30
-rw-r--r--source/blender/editors/gizmo_library/gizmo_draw_utils.c1
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c2
-rw-r--r--source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c2
-rw-r--r--source/blender/editors/gpencil/annotate_paint.c14
-rw-r--r--source/blender/editors/gpencil/gpencil_data.c148
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c19
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c55
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h1
-rw-r--r--source/blender/editors/gpencil/gpencil_mesh.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_ops.c1
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c28
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c20
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c43
-rw-r--r--source/blender/editors/gpencil/gpencil_vertex_paint.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_weight_paint.c4
-rw-r--r--source/blender/editors/include/BIF_glutil.h38
-rw-r--r--source/blender/editors/include/ED_buttons.h4
-rw-r--r--source/blender/editors/include/ED_numinput.h8
-rw-r--r--source/blender/editors/include/ED_screen.h12
-rw-r--r--source/blender/editors/include/ED_view3d.h11
-rw-r--r--source/blender/editors/include/UI_interface.h16
-rw-r--r--source/blender/editors/interface/interface.c271
-rw-r--r--source/blender/editors/interface/interface_anim.c40
-rw-r--r--source/blender/editors/interface/interface_context_menu.c4
-rw-r--r--source/blender/editors/interface/interface_draw.c38
-rw-r--r--source/blender/editors/interface/interface_eyedropper_color.c6
-rw-r--r--source/blender/editors/interface/interface_eyedropper_colorband.c4
-rw-r--r--source/blender/editors/interface/interface_eyedropper_gpencil_color.c9
-rw-r--r--source/blender/editors/interface/interface_handlers.c70
-rw-r--r--source/blender/editors/interface/interface_icons.c14
-rw-r--r--source/blender/editors/interface/interface_icons_event.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h106
-rw-r--r--source/blender/editors/interface/interface_layout.c126
-rw-r--r--source/blender/editors/interface/interface_ops.c9
-rw-r--r--source/blender/editors/interface/interface_query.c4
-rw-r--r--source/blender/editors/interface/interface_region_hud.c2
-rw-r--r--source/blender/editors/interface/interface_region_popup.c2
-rw-r--r--source/blender/editors/interface/interface_region_search.c74
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c12
-rw-r--r--source/blender/editors/interface/interface_style.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c75
-rw-r--r--source/blender/editors/interface/interface_utils.c2
-rw-r--r--source/blender/editors/interface/interface_widgets.c36
-rw-r--r--source/blender/editors/interface/view2d.c6
-rw-r--r--source/blender/editors/interface/view2d_ops.c2
-rw-r--r--source/blender/editors/mask/mask_draw.c5
-rw-r--r--source/blender/editors/mesh/editmesh_bevel.c12
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c6
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c2
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c7
-rw-r--r--source/blender/editors/mesh/editmesh_select.c4
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c2
-rw-r--r--source/blender/editors/object/object_add.c52
-rw-r--r--source/blender/editors/object/object_bake.c4
-rw-r--r--source/blender/editors/object/object_bake_api.c8
-rw-r--r--source/blender/editors/object/object_modifier.c20
-rw-r--r--source/blender/editors/object/object_relations.c3
-rw-r--r--source/blender/editors/object/object_remesh.c7
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/render/render_opengl.c9
-rw-r--r--source/blender/editors/render/render_preview.c15
-rw-r--r--source/blender/editors/screen/area.c58
-rw-r--r--source/blender/editors/screen/glutil.c143
-rw-r--r--source/blender/editors/screen/screen_context.c1
-rw-r--r--source/blender/editors/screen/screen_draw.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c55
-rw-r--r--source/blender/editors/screen/screen_intern.h10
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/editors/screen/workspace_edit.c31
-rw-r--r--source/blender/editors/screen/workspace_layout_edit.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c1099
-rw-r--r--source/blender/editors/sculpt_paint/paint_curve.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c18
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h1
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c54
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c53
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_cloth.c413
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_detail.c6
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_filter_mesh.c70
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h8
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_mask_expand.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c14
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_paint_color.c4
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_pose.c10
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c2
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_api/spacetypes.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_context.c132
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c44
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c99
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c2
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c4
-rw-r--r--source/blender/editors/space_clip/clip_draw.c6
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c10
-rw-r--r--source/blender/editors/space_clip/space_clip.c27
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c6
-rw-r--r--source/blender/editors/space_clip/tracking_select.c12
-rw-r--r--source/blender/editors/space_console/space_console.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c5
-rw-r--r--source/blender/editors/space_file/file_ops.c16
-rw-r--r--source/blender/editors/space_file/space_file.c8
-rw-r--r--source/blender/editors/space_graph/graph_edit.c2
-rw-r--r--source/blender/editors/space_graph/space_graph.c4
-rw-r--r--source/blender/editors/space_image/image_draw.c46
-rw-r--r--source/blender/editors/space_image/image_ops.c11
-rw-r--r--source/blender/editors/space_image/image_undo.c7
-rw-r--r--source/blender/editors/space_image/space_image.c4
-rw-r--r--source/blender/editors/space_info/info_draw.c4
-rw-r--r--source/blender/editors/space_info/space_info.c4
-rw-r--r--source/blender/editors/space_info/textview.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c2
-rw-r--r--source/blender/editors/space_nla/space_nla.c4
-rw-r--r--source/blender/editors/space_node/drawnode.c9
-rw-r--r--source/blender/editors/space_node/node_draw.c7
-rw-r--r--source/blender/editors/space_node/node_edit.c6
-rw-r--r--source/blender/editors/space_node/node_relationships.c6
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c4
-rw-r--r--source/blender/editors/space_script/space_script.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c123
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c18
-rw-r--r--source/blender/editors/space_statusbar/space_statusbar.c4
-rw-r--r--source/blender/editors/space_text/space_text.c4
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c2
-rw-r--r--source/blender/editors/space_topbar/space_topbar.c4
-rw-r--r--source/blender/editors/space_userpref/space_userpref.c6
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c9
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_ruler.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_placement.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c6
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_utils.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_constraints.c2
-rw-r--r--source/blender/editors/transform/transform_convert_gpencil.c2
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c9
-rw-r--r--source/blender/editors/transform/transform_gizmo_2d.c6
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c2
-rw-r--r--source/blender/editors/transform/transform_gizmo_extrude_3d.c2
-rw-r--r--source/blender/editors/transform/transform_mode.c4
-rw-r--r--source/blender/editors/transform/transform_mode_bbone_resize.c5
-rw-r--r--source/blender/editors/transform/transform_mode_edge_slide.c4
-rw-r--r--source/blender/editors/transform/transform_mode_shear.c10
-rw-r--r--source/blender/editors/transform/transform_mode_vert_slide.c6
-rw-r--r--source/blender/editors/transform/transform_snap.c30
-rw-r--r--source/blender/editors/transform/transform_snap_object.c10
-rw-r--r--source/blender/editors/util/numinput.c17
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h1
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c1
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c25
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c5
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c436
-rw-r--r--source/blender/freestyle/FRS_freestyle.h2
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp7
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp2
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp2
-rw-r--r--source/blender/freestyle/intern/geometry/GeomUtils.cpp10
-rw-r--r--source/blender/freestyle/intern/python/BPy_Convert.cpp38
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp12
-rw-r--r--source/blender/freestyle/intern/python/BPy_Id.cpp2
-rw-r--r--source/blender/freestyle/intern/python/BPy_IntegrationType.cpp13
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp8
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_ViewShape.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp8
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp3
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp3
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp6
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp2
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.cpp6
-rw-r--r--source/blender/freestyle/intern/stroke/StrokeRenderer.cpp5
-rw-r--r--source/blender/freestyle/intern/system/PseudoNoise.cpp5
-rw-r--r--source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp15
-rw-r--r--source/blender/freestyle/intern/view_map/OccluderSource.cpp9
-rw-r--r--source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp68
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp18
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp23
-rw-r--r--source/blender/freestyle/intern/winged_edge/WEdge.cpp7
-rw-r--r--source/blender/functions/CMakeLists.txt17
-rw-r--r--source/blender/functions/FN_array_spans.hh2
-rw-r--r--source/blender/functions/FN_attributes_ref.hh6
-rw-r--r--source/blender/functions/FN_cpp_type.hh16
-rw-r--r--source/blender/functions/FN_multi_function_params.hh46
-rw-r--r--source/blender/functions/FN_multi_function_signature.hh7
-rw-r--r--source/blender/functions/FN_spans.hh68
-rw-r--r--source/blender/functions/intern/attributes_ref.cc16
-rw-r--r--source/blender/functions/intern/multi_function_builder.cc4
-rw-r--r--source/blender/functions/intern/multi_function_network_evaluation.cc84
-rw-r--r--source/blender/functions/intern/multi_function_network_optimization.cc20
-rw-r--r--source/blender/functions/tests/FN_array_spans_test.cc132
-rw-r--r--source/blender/functions/tests/FN_attributes_ref_test.cc97
-rw-r--r--source/blender/functions/tests/FN_cpp_type_test.cc325
-rw-r--r--source/blender/functions/tests/FN_generic_vector_array_test.cc101
-rw-r--r--source/blender/functions/tests/FN_multi_function_network_test.cc255
-rw-r--r--source/blender/functions/tests/FN_multi_function_test.cc387
-rw-r--r--source/blender/functions/tests/FN_spans_test.cc222
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c5
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c4
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c8
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c2
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c2
-rw-r--r--source/blender/gpu/CMakeLists.txt40
-rw-r--r--source/blender/gpu/GPU_batch.h5
-rw-r--r--source/blender/gpu/GPU_debug.h2
-rw-r--r--source/blender/gpu/GPU_draw.h92
-rw-r--r--source/blender/gpu/GPU_extensions.h2
-rw-r--r--source/blender/gpu/GPU_framebuffer.h20
-rw-r--r--source/blender/gpu/GPU_immediate.h4
-rw-r--r--source/blender/gpu/GPU_init_exit.h2
-rw-r--r--source/blender/gpu/GPU_material.h11
-rw-r--r--source/blender/gpu/GPU_platform.h11
-rw-r--r--source/blender/gpu/GPU_shader.h2
-rw-r--r--source/blender/gpu/GPU_state.h1
-rw-r--r--source/blender/gpu/GPU_texture.h27
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h3
-rw-r--r--source/blender/gpu/GPU_vertex_buffer.h6
-rw-r--r--source/blender/gpu/GPU_vertex_format.h10
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding.cc (renamed from source/blender/gpu/intern/gpu_attr_binding.c)0
-rw-r--r--source/blender/gpu/intern/gpu_attr_binding_private.h9
-rw-r--r--source/blender/gpu/intern/gpu_batch.cc (renamed from source/blender/gpu/intern/gpu_batch.c)74
-rw-r--r--source/blender/gpu/intern/gpu_batch_presets.c12
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c13
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c552
-rw-r--r--source/blender/gpu/intern/gpu_codegen.h8
-rw-r--r--source/blender/gpu/intern/gpu_context.cc (renamed from source/blender/gpu/intern/gpu_context.cpp)0
-rw-r--r--source/blender/gpu/intern/gpu_debug.cc (renamed from source/blender/gpu/intern/gpu_debug.c)0
-rw-r--r--source/blender/gpu/intern/gpu_draw.c1469
-rw-r--r--source/blender/gpu/intern/gpu_element.cc (renamed from source/blender/gpu/intern/gpu_element.c)35
-rw-r--r--source/blender/gpu/intern/gpu_extensions.cc (renamed from source/blender/gpu/intern/gpu_extensions.c)16
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.cc (renamed from source/blender/gpu/intern/gpu_framebuffer.c)103
-rw-r--r--source/blender/gpu/intern/gpu_immediate.cc (renamed from source/blender/gpu/intern/gpu_immediate.c)47
-rw-r--r--source/blender/gpu/intern/gpu_immediate_util.c24
-rw-r--r--source/blender/gpu/intern/gpu_init_exit.c2
-rw-r--r--source/blender/gpu/intern/gpu_material.c15
-rw-r--r--source/blender/gpu/intern/gpu_material_library.c13
-rw-r--r--source/blender/gpu/intern/gpu_matrix.cc (renamed from source/blender/gpu/intern/gpu_matrix.c)51
-rw-r--r--source/blender/gpu/intern/gpu_node_graph.h1
-rw-r--r--source/blender/gpu/intern/gpu_platform.cc (renamed from source/blender/gpu/intern/gpu_platform.c)0
-rw-r--r--source/blender/gpu/intern/gpu_primitive.c29
-rw-r--r--source/blender/gpu/intern/gpu_primitive_private.h9
-rw-r--r--source/blender/gpu/intern/gpu_private.h8
-rw-r--r--source/blender/gpu/intern/gpu_select.c1
-rw-r--r--source/blender/gpu/intern/gpu_select_pick.c15
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c5
-rw-r--r--source/blender/gpu/intern/gpu_shader.cc838
-rw-r--r--source/blender/gpu/intern/gpu_shader_builtin.c (renamed from source/blender/gpu/intern/gpu_shader.c)727
-rw-r--r--source/blender/gpu/intern/gpu_shader_interface.cc (renamed from source/blender/gpu/intern/gpu_shader_interface.c)132
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h11
-rw-r--r--source/blender/gpu/intern/gpu_state.cc (renamed from source/blender/gpu/intern/gpu_state.c)72
-rw-r--r--source/blender/gpu/intern/gpu_texture.cc (renamed from source/blender/gpu/intern/gpu_texture.c)531
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.cc (renamed from source/blender/gpu/intern/gpu_uniformbuffer.c)315
-rw-r--r--source/blender/gpu/intern/gpu_vertex_buffer.cc (renamed from source/blender/gpu/intern/gpu_vertex_buffer.c)25
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc (renamed from source/blender/gpu/intern/gpu_vertex_format.c)57
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format_private.h9
-rw-r--r--source/blender/gpu/intern/gpu_viewport.c6
-rw-r--r--source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl87
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl12
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl2
-rw-r--r--source/blender/ikplugin/BIK_api.h8
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c2
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c29
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp25
-rw-r--r--source/blender/imbuf/CMakeLists.txt2
-rw-r--r--source/blender/imbuf/IMB_imbuf.h25
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c5
-rw-r--r--source/blender/imbuf/intern/anim_movie.c4
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c29
-rw-r--r--source/blender/imbuf/intern/cineon/logmemfile.c36
-rw-r--r--source/blender/imbuf/intern/colormanagement.c12
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp50
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp115
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp2
-rw-r--r--source/blender/imbuf/intern/filter.c5
-rw-r--r--source/blender/imbuf/intern/indexer.c10
-rw-r--r--source/blender/imbuf/intern/iris.c7
-rw-r--r--source/blender/imbuf/intern/jp2.c25
-rw-r--r--source/blender/imbuf/intern/moviecache.c5
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp28
-rw-r--r--source/blender/imbuf/intern/stereoimbuf.c92
-rw-r--r--source/blender/imbuf/intern/tiff.c18
-rw-r--r--source/blender/imbuf/intern/util_gpu.c260
-rw-r--r--source/blender/io/alembic/ABC_alembic.h10
-rw-r--r--source/blender/io/alembic/intern/abc_axis_conversion.cc2
-rw-r--r--source/blender/io/alembic/intern/abc_axis_conversion.h2
-rw-r--r--source/blender/io/alembic/intern/alembic_capi.cc146
-rw-r--r--source/blender/io/avi/intern/avi.c10
-rw-r--r--source/blender/io/avi/intern/avi_rgb.c45
-rw-r--r--source/blender/io/collada/AnimationExporter.cpp23
-rw-r--r--source/blender/io/collada/AnimationImporter.cpp162
-rw-r--r--source/blender/io/collada/BCAnimationCurve.cpp5
-rw-r--r--source/blender/io/collada/DocumentImporter.cpp3
-rw-r--r--source/blender/io/collada/collada_internal.cpp2
-rw-r--r--source/blender/io/collada/collada_utils.cpp28
-rw-r--r--source/blender/makesdna/DNA_brush_types.h39
-rw-r--r--source/blender/makesdna/DNA_cachefile_types.h13
-rw-r--r--source/blender/makesdna/DNA_curve_types.h9
-rw-r--r--source/blender/makesdna/DNA_curveprofile_types.h2
-rw-r--r--source/blender/makesdna/DNA_image_types.h18
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h32
-rw-r--r--source/blender/makesdna/DNA_movieclip_types.h4
-rw-r--r--source/blender/makesdna/DNA_rigidbody_types.h2
-rw-r--r--source/blender/makesdna/DNA_simulation_types.h36
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h2
-rw-r--r--source/blender/makesdna/DNA_view2d_types.h2
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h4
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c245
-rw-r--r--source/blender/makesdna/intern/dna_rename_defs.h2
-rw-r--r--source/blender/makesdna/intern/dna_utils.c4
-rw-r--r--source/blender/makesdna/intern/makesdna.c17
-rw-r--r--source/blender/makesrna/intern/makesrna.c4
-rw-r--r--source/blender/makesrna/intern/rna_brush.c81
-rw-r--r--source/blender/makesrna/intern/rna_cachefile.c26
-rw-r--r--source/blender/makesrna/intern/rna_color.c2
-rw-r--r--source/blender/makesrna/intern/rna_context.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve.c8
-rw-r--r--source/blender/makesrna/intern/rna_curveprofile.c2
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c2
-rw-r--r--source/blender/makesrna/intern/rna_fluid.c11
-rw-r--r--source/blender/makesrna/intern/rna_image.c7
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c15
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c110
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c19
-rw-r--r--source/blender/makesrna/intern/rna_object.c9
-rw-r--r--source/blender/makesrna/intern/rna_particle.c2
-rw-r--r--source/blender/makesrna/intern/rna_rigidbody.c5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c4
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c9
-rw-r--r--source/blender/makesrna/intern/rna_screen.c2
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c5
-rw-r--r--source/blender/makesrna/intern/rna_space.c97
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c12
-rw-r--r--source/blender/modifiers/intern/MOD_array.c11
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c5
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c5
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c4
-rw-r--r--source/blender/modifiers/intern/MOD_mask.cc5
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c25
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c25
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c22
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c34
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c9
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c4
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c2
-rw-r--r--source/blender/modifiers/intern/MOD_simulation.cc14
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c12
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_extrude.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify_nonmanifold.c11
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c9
-rw-r--r--source/blender/modifiers/intern/MOD_ui_common.c7
-rw-r--r--source/blender/modifiers/intern/MOD_util.c7
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c6
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c7
-rw-r--r--source/blender/modifiers/intern/MOD_weightvg_util.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c17
-rw-r--r--source/blender/modifiers/intern/MOD_weld.c63
-rw-r--r--source/blender/nodes/CMakeLists.txt7
-rw-r--r--source/blender/nodes/NOD_derived_node_tree.hh11
-rw-r--r--source/blender/nodes/NOD_function.h1
-rw-r--r--source/blender/nodes/NOD_node_tree_dependencies.hh76
-rw-r--r--source/blender/nodes/NOD_node_tree_multi_function.hh6
-rw-r--r--source/blender/nodes/NOD_node_tree_ref.hh11
-rw-r--r--source/blender/nodes/NOD_simulation.h2
-rw-r--r--source/blender/nodes/NOD_static_types.h4
-rw-r--r--source/blender/nodes/function/nodes/node_fn_random_float.cc89
-rw-r--r--source/blender/nodes/intern/derived_node_tree.cc4
-rw-r--r--source/blender/nodes/intern/node_common.c10
-rw-r--r--source/blender/nodes/intern/node_socket.cc6
-rw-r--r--source/blender/nodes/intern/node_tree_dependencies.cc57
-rw-r--r--source/blender/nodes/intern/node_tree_multi_function.cc11
-rw-r--r--source/blender/nodes/intern/node_tree_ref.cc2
-rw-r--r--source/blender/nodes/intern/node_util.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_attribute.c15
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_clamp.cc (renamed from source/blender/nodes/shader/nodes/node_shader_clamp.c)24
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c29
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_displacement.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_geometry.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mapping.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.cc5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_mixRgb.c9
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tangent.c37
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_environment.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_sky.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_valToRgb.cc5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_displacement.c7
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_math.cc5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vector_rotate.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_wireframe.c18
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc38
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc36
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc3
-rw-r--r--source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc3
-rw-r--r--source/blender/nodes/texture/node_texture_util.c13
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_curves.c2
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_rotate.c2
-rw-r--r--source/blender/python/BPY_extern.h8
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c8
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c24
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c680
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c108
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c113
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_select.c76
-rw-r--r--source/blender/python/bmesh/bmesh_py_utils.c63
-rw-r--r--source/blender/python/generic/bgl.c2293
-rw-r--r--source/blender/python/generic/idprop_py_api.c124
-rw-r--r--source/blender/python/generic/imbuf_py_api.c14
-rw-r--r--source/blender/python/generic/py_capi_utils.c234
-rw-r--r--source/blender/python/gpu/gpu_py_api.c4
-rw-r--r--source/blender/python/gpu/gpu_py_api.h6
-rw-r--r--source/blender/python/gpu/gpu_py_batch.c9
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c18
-rw-r--r--source/blender/python/intern/bpy_capi_utils.c39
-rw-r--r--source/blender/python/intern/bpy_capi_utils.h2
-rw-r--r--source/blender/python/intern/bpy_driver.c35
-rw-r--r--source/blender/python/intern/bpy_interface.c52
-rw-r--r--source/blender/python/intern/bpy_library_load.c118
-rw-r--r--source/blender/python/intern/bpy_props.c58
-rw-r--r--source/blender/python/intern/bpy_rna.c839
-rw-r--r--source/blender/python/intern/bpy_rna_anim.c216
-rw-r--r--source/blender/python/intern/bpy_rna_array.c125
-rw-r--r--source/blender/python/intern/bpy_rna_callback.c76
-rw-r--r--source/blender/python/intern/bpy_rna_gizmo.c8
-rw-r--r--source/blender/python/mathutils/mathutils.c101
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c34
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c34
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c245
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c47
-rw-r--r--source/blender/python/mathutils/mathutils_Vector.c109
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c88
-rw-r--r--source/blender/python/mathutils/mathutils_geometry.c284
-rw-r--r--source/blender/render/intern/source/imagetexture.c6
-rw-r--r--source/blender/render/intern/source/multires_bake.c2
-rw-r--r--source/blender/render/intern/source/pipeline.c44
-rw-r--r--source/blender/render/intern/source/pointdensity.c4
-rw-r--r--source/blender/render/intern/source/render_result.c16
-rw-r--r--source/blender/render/intern/source/render_texture.c27
-rw-r--r--source/blender/simulation/CMakeLists.txt4
-rw-r--r--source/blender/simulation/SIM_simulation_update.hh4
-rw-r--r--source/blender/simulation/intern/hair_volume.cpp16
-rw-r--r--source/blender/simulation/intern/implicit_blender.c72
-rw-r--r--source/blender/simulation/intern/particle_allocator.cc11
-rw-r--r--source/blender/simulation/intern/particle_allocator.hh5
-rw-r--r--source/blender/simulation/intern/particle_function.cc33
-rw-r--r--source/blender/simulation/intern/particle_function.hh15
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.cc362
-rw-r--r--source/blender/simulation/intern/particle_mesh_emitter.hh49
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.cc878
-rw-r--r--source/blender/simulation/intern/simulation_collect_influences.hh2
-rw-r--r--source/blender/simulation/intern/simulation_solver.cc410
-rw-r--r--source/blender/simulation/intern/simulation_solver.hh247
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.cc57
-rw-r--r--source/blender/simulation/intern/simulation_solver_influences.hh234
-rw-r--r--source/blender/simulation/intern/simulation_update.cc233
-rw-r--r--source/blender/simulation/intern/time_interval.hh40
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo.c5
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c23
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c21
-rw-r--r--source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c12
-rw-r--r--source/blender/windowmanager/intern/wm.c12
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c8
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c10
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c13
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c311
-rw-r--r--source/blender/windowmanager/intern/wm_files.c28
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c6
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c16
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c11
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c4
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c16
-rw-r--r--source/blender/windowmanager/intern/wm_keymap_utils.c20
-rw-r--r--source/blender/windowmanager/intern/wm_operator_type.c8
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c334
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c5
-rw-r--r--source/blender/windowmanager/intern/wm_stereo.c15
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c1
-rw-r--r--source/blender/windowmanager/intern/wm_window.c38
-rw-r--r--source/blender/windowmanager/wm_draw.h2
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c15
928 files changed, 26621 insertions, 17854 deletions
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 2f7d5a60a6f..95b074fa2df 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -509,7 +509,7 @@ void BLF_color4fv(int fontid, const float rgba[4])
void BLF_color4f(int fontid, float r, float g, float b, float a)
{
- float rgba[4] = {r, g, b, a};
+ const float rgba[4] = {r, g, b, a};
BLF_color4fv(fontid, rgba);
}
@@ -523,7 +523,7 @@ void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha)
void BLF_color3f(int fontid, float r, float g, float b)
{
- float rgba[4] = {r, g, b, 1.0f};
+ const float rgba[4] = {r, g, b, 1.0f};
BLF_color4fv(fontid, rgba);
}
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 50a8223a84c..ff31878a929 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -194,6 +194,8 @@ static GPUTexture *blf_batch_cache_texture_load(void)
int offset_x = bitmap_len_landed % tex_width;
int offset_y = bitmap_len_landed / tex_width;
+ GPU_texture_bind(gc->texture, 0);
+
/* TODO(germano): Update more than one row in a single call. */
while (remain) {
int remain_row = tex_width - offset_x;
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 797c4f9f355..ae0a669bfb3 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -31,15 +31,15 @@ extern "C" {
*/
/* Blender major and minor version. */
-#define BLENDER_VERSION 290
+#define BLENDER_VERSION 291
/* Blender patch version for bugfix releases. */
#define BLENDER_VERSION_PATCH 0
/** Blender release cycle stage: alpha/beta/rc/release. */
-#define BLENDER_VERSION_CYCLE beta
+#define BLENDER_VERSION_CYCLE alpha
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 7
+#define BLENDER_FILE_SUBVERSION 0
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 5a68514a387..1ada83c0163 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -69,7 +69,7 @@ void BKE_curvemapping_changed(struct CurveMapping *cumap, const bool rem_doubles
void BKE_curvemapping_changed_all(struct CurveMapping *cumap);
/* call before _all_ evaluation functions */
-void BKE_curvemapping_initialize(struct CurveMapping *cumap);
+void BKE_curvemapping_init(struct CurveMapping *cumap);
/* keep these (const CurveMap) - to help with thread safety */
/* single curve, no table check */
diff --git a/source/blender/blenkernel/BKE_curveprofile.h b/source/blender/blenkernel/BKE_curveprofile.h
index 84dbcd25b32..9c72a866fa9 100644
--- a/source/blender/blenkernel/BKE_curveprofile.h
+++ b/source/blender/blenkernel/BKE_curveprofile.h
@@ -71,7 +71,7 @@ void BKE_curveprofile_create_samples(struct CurveProfile *profile,
bool sample_straight_edges,
struct CurveProfilePoint *r_samples);
-void BKE_curveprofile_initialize(struct CurveProfile *profile, short segments_len);
+void BKE_curveprofile_init(struct CurveProfile *profile, short segments_len);
/* Called for a complete update of the widget after modifications */
enum {
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index a18084f8bbd..f052ba400fc 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -54,6 +54,7 @@ void BKE_image_free_packedfiles(struct Image *image);
void BKE_image_free_views(struct Image *image);
void BKE_image_free_buffers(struct Image *image);
void BKE_image_free_buffers_ex(struct Image *image, bool do_lock);
+void BKE_image_free_gputextures(struct Image *ima);
/* call from library */
void BKE_image_free(struct Image *image);
@@ -273,6 +274,10 @@ void BKE_image_free_anim_ibufs(struct Image *ima, int except_frame);
/* does all images with type MOVIE or SEQUENCE */
void BKE_image_all_free_anim_ibufs(struct Main *bmain, int except_frame);
+void BKE_image_free_all_gputextures(struct Main *bmain);
+void BKE_image_free_anim_gputextures(struct Main *bmain);
+void BKE_image_free_old_gputextures(struct Main *bmain);
+
bool BKE_image_memorypack(struct Image *ima);
void BKE_image_packfiles(struct ReportList *reports, struct Image *ima, const char *basepath);
void BKE_image_packfiles_from_mem(struct ReportList *reports,
@@ -361,6 +366,30 @@ bool BKE_image_has_loaded_ibuf(struct Image *image);
struct ImBuf *BKE_image_get_ibuf_with_name(struct Image *image, const char *name);
struct ImBuf *BKE_image_get_first_ibuf(struct Image *image);
+/* Not to be use directly. */
+struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, struct ImBuf *ibuf);
+
+/* Get the GPUTexture for a given `Image`.
+ *
+ * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already
+ * available. It is also required when requesting the GPUTexture for a render result. */
+struct GPUTexture *BKE_image_get_gpu_texture(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tiles(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+struct GPUTexture *BKE_image_get_gpu_tilemap(struct Image *image,
+ struct ImageUser *iuser,
+ struct ImBuf *ibuf);
+
+void BKE_image_update_gputexture(
+ struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
+void BKE_image_paint_set_mipmap(struct Main *bmain, bool mipmap);
+
+/* Delayed free of OpenGL buffers by main thread */
+void BKE_image_free_unused_gpu_textures(void);
+
struct RenderSlot *BKE_image_add_renderslot(struct Image *ima, const char *name);
bool BKE_image_remove_renderslot(struct Image *ima, struct ImageUser *iuser, int slot);
struct RenderSlot *BKE_image_get_renderslot(struct Image *ima, int slot);
diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h
index 5af73a1579d..5843992b25c 100644
--- a/source/blender/blenkernel/BKE_lib_override.h
+++ b/source/blender/blenkernel/BKE_lib_override.h
@@ -140,7 +140,7 @@ void BKE_lib_override_library_main_update(struct Main *bmain);
/* For now, we just use a temp main list. */
typedef struct Main OverrideLibraryStorage;
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void);
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void);
struct ID *BKE_lib_override_library_operations_store_start(
struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local);
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage,
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index d1f6efc035b..958fbef1f97 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -112,6 +112,11 @@ bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip,
struct MovieClipUser *user,
struct ImBuf *ibuf);
+struct GPUTexture *BKE_movieclip_get_gpu_texture(struct MovieClip *clip,
+ struct MovieClipUser *cuser);
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip);
+
/* Dependency graph evaluation. */
void BKE_movieclip_eval_update(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index b9e2531755b..ef46bc0f202 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1330,6 +1330,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define SIM_NODE_EMIT_PARTICLES 1009
#define SIM_NODE_TIME 1010
#define SIM_NODE_PARTICLE_ATTRIBUTE 1011
+#define SIM_NODE_AGE_REACHED_EVENT 1012
+#define SIM_NODE_KILL_PARTICLE 1013
/** \} */
@@ -1343,6 +1345,7 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
#define FN_NODE_GROUP_INSTANCE_ID 1203
#define FN_NODE_COMBINE_STRINGS 1204
#define FN_NODE_OBJECT_TRANSFORMS 1205
+#define FN_NODE_RANDOM_FLOAT 1206
/** \} */
diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h
index 6d488cc3142..1f8cdf27eb1 100644
--- a/source/blender/blenkernel/BKE_ocean.h
+++ b/source/blender/blenkernel/BKE_ocean.h
@@ -69,8 +69,10 @@ typedef struct OceanCache {
struct Ocean *BKE_ocean_add(void);
void BKE_ocean_free_data(struct Ocean *oc);
void BKE_ocean_free(struct Ocean *oc);
-bool BKE_ocean_ensure(struct OceanModifierData *omd);
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd);
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution);
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution);
void BKE_ocean_init(struct Ocean *o,
int M,
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e2381bf68ac..4e520948bcb 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -41,6 +41,7 @@ struct EdgeSet;
struct GHash;
struct GridPaintMask;
struct ImagePool;
+struct ListBase;
struct MLoop;
struct MLoopTri;
struct MVert;
@@ -259,10 +260,20 @@ typedef struct SculptPoseIKChain {
/* Cloth Brush */
typedef struct SculptClothLengthConstraint {
- int v1;
- int v2;
+ /* Elements that are affected by the constraint. */
+ /* Element a should always be a mesh vertex with the index stored in elem_index_a as it is always
+ * deformed. Element b could be another vertex of the same mesh or any other position (arbitrary
+ * point, position for a previous state). In that case, elem_index_a and elem_index_b should be
+ * the same to avoid affecting two different vertices when solving the constraints.
+ * *elem_position points to the position which is owned by the element. */
+ int elem_index_a;
+ float *elem_position_a;
+
+ int elem_index_b;
+ float *elem_position_b;
float length;
+ float strength;
} SculptClothLengthConstraint;
typedef struct SculptClothSimulation {
@@ -272,6 +283,11 @@ typedef struct SculptClothSimulation {
int capacity_length_constraints;
float *length_constraint_tweak;
+ /* Position anchors for deformation brushes. These positions are modified by the brush and the
+ * final positions of the simulated vertices are updated with constraints that use these points
+ * as targets. */
+ float (*deformation_pos)[3];
+
float mass;
float damping;
@@ -279,7 +295,9 @@ typedef struct SculptClothSimulation {
float (*pos)[3];
float (*init_pos)[3];
float (*prev_pos)[3];
+ float (*last_iteration_pos)[3];
+ struct ListBase *collider_list;
} SculptClothSimulation;
typedef struct SculptPersistentBase {
@@ -317,6 +335,9 @@ typedef struct SculptSession {
int level;
} multires;
+ /* Depsgraph for the Cloth Brush solver to get the colliders. */
+ struct Depsgraph *depsgraph;
+
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
struct MPoly *mpoly;
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 1e7a4ae75fb..7d317538f44 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -579,7 +579,7 @@ void psys_particle_on_dm(struct Mesh *mesh_final,
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
-void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
+void init_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
void psys_calc_dmcache(struct Object *ob,
struct Mesh *mesh_final,
struct Mesh *mesh_original,
diff --git a/source/blender/blenkernel/BKE_persistent_data_handle.hh b/source/blender/blenkernel/BKE_persistent_data_handle.hh
index c8e02062f0b..bcc84f9c9d0 100644
--- a/source/blender/blenkernel/BKE_persistent_data_handle.hh
+++ b/source/blender/blenkernel/BKE_persistent_data_handle.hh
@@ -84,45 +84,45 @@ class PersistentObjectHandle : public PersistentIDHandle {
class PersistentDataHandleMap {
private:
- Map<int32_t, const ID *> id_by_handle_;
- Map<const ID *, int32_t> handle_by_id_;
+ Map<int32_t, ID *> id_by_handle_;
+ Map<ID *, int32_t> handle_by_id_;
public:
- void add(int32_t handle, const ID &id)
+ void add(int32_t handle, ID &id)
{
BLI_assert(handle >= 0);
handle_by_id_.add(&id, handle);
id_by_handle_.add(handle, &id);
}
- PersistentIDHandle lookup(const ID *id) const
+ PersistentIDHandle lookup(ID *id) const
{
const int handle = handle_by_id_.lookup_default(id, -1);
return PersistentIDHandle(handle);
}
- PersistentObjectHandle lookup(const Object *object) const
+ PersistentObjectHandle lookup(Object *object) const
{
- const int handle = handle_by_id_.lookup_default((const ID *)object, -1);
+ const int handle = handle_by_id_.lookup_default((ID *)object, -1);
return PersistentObjectHandle(handle);
}
- const ID *lookup(const PersistentIDHandle &handle) const
+ ID *lookup(const PersistentIDHandle &handle) const
{
- const ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr);
+ ID *id = id_by_handle_.lookup_default(handle.handle_, nullptr);
return id;
}
- const Object *lookup(const PersistentObjectHandle &handle) const
+ Object *lookup(const PersistentObjectHandle &handle) const
{
- const ID *id = this->lookup((const PersistentIDHandle &)handle);
+ ID *id = this->lookup((const PersistentIDHandle &)handle);
if (id == nullptr) {
return nullptr;
}
if (GS(id->name) != ID_OB) {
return nullptr;
}
- return (const Object *)id;
+ return (Object *)id;
}
};
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 735d6dc6e89..edab543fc37 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -72,7 +72,7 @@ typedef struct SpaceType {
/* Initial allocation, after this WM will call init() too. Some editors need
* area and scene data (e.g. frame range) to set their initial scrolling. */
- struct SpaceLink *(*new)(const struct ScrArea *area, const struct Scene *scene);
+ struct SpaceLink *(*create)(const struct ScrArea *area, const struct Scene *scene);
/* not free spacelink itself */
void (*free)(struct SpaceLink *sl);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 03f14be8772..b6d901c8ef2 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -627,6 +627,10 @@ void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb,
void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra);
bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports);
bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq);
+void BKE_sequencer_flag_for_removal(struct Scene *scene,
+ struct ListBase *seqbase,
+ struct Sequence *seq);
+void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase);
/* A debug and development function which checks whether sequences have unique UUIDs.
* Errors will be reported to the console. */
diff --git a/source/blender/blenkernel/BKE_simulation.h b/source/blender/blenkernel/BKE_simulation.h
index 98d1cf1e9b5..2c436f2bff8 100644
--- a/source/blender/blenkernel/BKE_simulation.h
+++ b/source/blender/blenkernel/BKE_simulation.h
@@ -31,6 +31,7 @@ void *BKE_simulation_add(struct Main *bmain, const char *name);
void BKE_simulation_data_update(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Simulation *simulation);
+void BKE_simulation_update_dependencies(struct Simulation *simulation, struct Main *bmain);
SimulationState *BKE_simulation_state_add(Simulation *simulation,
const char *type,
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index d702da55ea8..ada341ff570 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -100,6 +100,7 @@ set(SRC
intern/context.c
intern/crazyspace.c
intern/curve.c
+ intern/curve_bevel.c
intern/curve_decimate.c
intern/curve_deform.c
intern/curveprofile.c
@@ -134,6 +135,7 @@ set(SRC
intern/idtype.c
intern/image.c
intern/image_gen.c
+ intern/image_gpu.c
intern/image_save.c
intern/ipo.c
intern/kelvinlet.c
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index e035d5cbb68..8d8301362b3 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -32,8 +32,6 @@
#include "CCGSubSurf.h"
#include "CCGSubSurf_intern.h"
-#include "GPU_glew.h"
-
/***/
int BKE_ccg_gridsize(int level)
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 8031e3dadf8..af4829691c2 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -80,11 +80,9 @@
//#define USE_MODIFIER_VALIDATE
#ifdef USE_MODIFIER_VALIDATE
-# define ASSERT_IS_VALID_DM(dm) (BLI_assert((dm == NULL) || (DM_is_valid(dm) == true)))
# define ASSERT_IS_VALID_MESH(mesh) \
(BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
#else
-# define ASSERT_IS_VALID_DM(dm)
# define ASSERT_IS_VALID_MESH(mesh)
#endif
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index ea5a4bd99d1..5b5e32f1d81 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1150,7 +1150,7 @@ static int nlaevalchan_validate_index(NlaEvalChannel *nec, int index)
return 0;
}
-/* Initialise default values for NlaEvalChannel from the property data. */
+/* Initialize default values for NlaEvalChannel from the property data. */
static void nlaevalchan_get_default_values(NlaEvalChannel *nec, float *r_values)
{
PointerRNA *ptr = &nec->key.ptr;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 985be4ac99f..631ce4edd20 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -2582,7 +2582,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
}
/* 2a. construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, ob, ctime);
+ BIK_init_tree(depsgraph, scene, ob, ctime);
/* 2b. construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index d66991aed70..97c717572bc 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -658,7 +658,7 @@ void BKE_pose_eval_init_ik(struct Depsgraph *depsgraph, Scene *scene, Object *ob
return;
}
/* construct the IK tree (standard IK) */
- BIK_initialize_tree(depsgraph, scene, object, ctime);
+ BIK_init_tree(depsgraph, scene, object, ctime);
/* construct the Spline IK trees
* - this is not integrated as an IK plugin, since it should be able
* to function in conjunction with standard IK. */
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index a0da1b1677d..a7324ffe738 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -873,7 +873,7 @@ static Object *boid_find_ground(BoidBrainData *bbd,
return bpa->ground;
}
- float zvec[3] = {0.0f, 0.0f, 2000.0f};
+ const float zvec[3] = {0.0f, 0.0f, 2000.0f};
ParticleCollision col;
ColliderCache *coll;
BVHTreeRayHit hit;
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 7223187831e..ce0249c71ce 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -557,7 +557,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INK);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INK;
@@ -594,7 +594,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_INKNOISE);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_INKNOISE;
@@ -631,7 +631,7 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_MARKER);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_MARKER;
@@ -667,12 +667,12 @@ void BKE_gpencil_brush_preset_set(Main *bmain, Brush *brush, const short type)
/* Curve. */
custom_curve = brush->gpencil_settings->curve_sensitivity;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 3, GPCURVE_PRESET_CHISEL_SENSIVITY);
custom_curve = brush->gpencil_settings->curve_strength;
BKE_curvemapping_set_defaults(custom_curve, 0, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(custom_curve);
+ BKE_curvemapping_init(custom_curve);
brush_gpencil_curvemap_reset(custom_curve->cm, 4, GPCURVE_PRESET_CHISEL_STRENGTH);
brush->gpencil_settings->icon_id = GP_BRUSH_ICON_CHISEL;
@@ -1740,7 +1740,7 @@ float BKE_brush_sample_tex_3d(const Scene *scene,
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
float rotation = -mtex->rot;
- float point_2d[2] = {point[0], point[1]};
+ const float point_2d[2] = {point[0], point[1]};
float x, y;
float co[3];
@@ -1770,7 +1770,7 @@ float BKE_brush_sample_tex_3d(const Scene *scene,
}
else {
float rotation = -mtex->rot;
- float point_2d[2] = {point[0], point[1]};
+ const float point_2d[2] = {point[0], point[1]};
float x = 0.0f, y = 0.0f; /* Quite warnings */
float invradius = 1.0f; /* Quite warnings */
float co[3];
@@ -1853,7 +1853,7 @@ float BKE_brush_sample_masktex(
}
if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
float rotation = -mtex->rot;
- float point_2d[2] = {point[0], point[1]};
+ const float point_2d[2] = {point[0], point[1]};
float x, y;
float co[3];
@@ -1883,7 +1883,7 @@ float BKE_brush_sample_masktex(
}
else {
float rotation = -mtex->rot;
- float point_2d[2] = {point[0], point[1]};
+ const float point_2d[2] = {point[0], point[1]};
float x = 0.0f, y = 0.0f; /* Quite warnings */
float invradius = 1.0f; /* Quite warnings */
float co[3];
@@ -2274,7 +2274,7 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
int half = side / 2;
int i, j;
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
texcache = BKE_brush_gen_texture_cache(br, half, secondary);
im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
im->x = im->y = side;
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index da9dab36044..9ad6ae84c5c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -61,6 +61,8 @@ static void cache_file_init_data(ID *id)
BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(cache_file, id));
cache_file->scale = 1.0f;
+ cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
+ BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name));
}
static void cache_file_copy_data(Main *UNUSED(bmain),
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 7c0e4064cdb..d8b4150b2b1 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -186,9 +186,8 @@ int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
if (sizex >= sizey) {
return CAMERA_SENSOR_FIT_HOR;
}
- else {
- return CAMERA_SENSOR_FIT_VERT;
- }
+
+ return CAMERA_SENSOR_FIT_VERT;
}
return sensor_fit;
@@ -636,64 +635,63 @@ static bool camera_frame_fit_calc_from_data(CameraParams *params,
return true;
}
- else {
- float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
- float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
- float plane_isect_pt_1[3], plane_isect_pt_2[3];
+ float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
+ float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];
- /* apply the dist-from-plane's to the transformed plane points */
- for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
- float co[3];
- mul_v3_v3fl(co, data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
- plane_from_point_normal_v3(plane_tx[i], co, data->normal_tx[i]);
- }
+ float plane_isect_pt_1[3], plane_isect_pt_2[3];
- if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) ||
- (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) {
- return false;
- }
+ /* apply the dist-from-plane's to the transformed plane points */
+ for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
+ float co[3];
+ mul_v3_v3fl(co, data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
+ plane_from_point_normal_v3(plane_tx[i], co, data->normal_tx[i]);
+ }
- add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
- add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
+ if ((!isect_plane_plane_v3(plane_tx[0], plane_tx[2], plane_isect_1, plane_isect_1_no)) ||
+ (!isect_plane_plane_v3(plane_tx[1], plane_tx[3], plane_isect_2, plane_isect_2_no))) {
+ return false;
+ }
- if (isect_line_line_v3(plane_isect_1,
- plane_isect_1_other,
- plane_isect_2,
- plane_isect_2_other,
- plane_isect_pt_1,
- plane_isect_pt_2) != 0) {
- float cam_plane_no[3];
- float plane_isect_delta[3];
- float plane_isect_delta_len;
+ add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
+ add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);
- float shift_fac = BKE_camera_sensor_size(
- params->sensor_fit, params->sensor_x, params->sensor_y) /
- params->lens;
+ if (isect_line_line_v3(plane_isect_1,
+ plane_isect_1_other,
+ plane_isect_2,
+ plane_isect_2_other,
+ plane_isect_pt_1,
+ plane_isect_pt_2) != 0) {
+ float cam_plane_no[3];
+ float plane_isect_delta[3];
+ float plane_isect_delta_len;
- /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
- negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);
+ float shift_fac = BKE_camera_sensor_size(
+ params->sensor_fit, params->sensor_x, params->sensor_y) /
+ params->lens;
- sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
- plane_isect_delta_len = len_v3(plane_isect_delta);
+ /* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
+ negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);
- if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
- copy_v3_v3(r_co, plane_isect_pt_1);
+ sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
+ plane_isect_delta_len = len_v3(plane_isect_delta);
- /* offset shift */
- normalize_v3(plane_isect_1_no);
- madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
- }
- else {
- copy_v3_v3(r_co, plane_isect_pt_2);
+ if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
+ copy_v3_v3(r_co, plane_isect_pt_1);
- /* offset shift */
- normalize_v3(plane_isect_2_no);
- madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
- }
+ /* offset shift */
+ normalize_v3(plane_isect_1_no);
+ madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
+ }
+ else {
+ copy_v3_v3(r_co, plane_isect_pt_2);
- return true;
+ /* offset shift */
+ normalize_v3(plane_isect_2_no);
+ madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
}
+
+ return true;
}
return false;
@@ -775,11 +773,10 @@ static void camera_stereo3d_model_matrix(const Object *camera,
camera_model_matrix(camera, r_modelmat);
return;
}
- else {
- float size[3];
- mat4_to_size(size, camera->obmat);
- size_to_mat4(sizemat, size);
- }
+
+ float size[3];
+ mat4_to_size(size, camera->obmat);
+ size_to_mat4(sizemat, size);
if (pivot == CAM_S3D_PIVOT_CENTER) {
fac = 0.5f;
@@ -931,9 +928,8 @@ bool BKE_camera_multiview_spherical_stereo(const RenderData *rd, const Object *c
if (camera->type != OB_CAMERA) {
return false;
}
- else {
- cam = camera->data;
- }
+
+ cam = camera->data;
if ((rd->views_format == SCE_VIEWS_FORMAT_STEREO_3D) && ELEM(cam->type, CAM_PANO, CAM_PERSP) &&
((cam->stereo.flag & CAM_S3D_SPHERICAL) != 0)) {
@@ -984,13 +980,12 @@ Object *BKE_camera_multiview_render(const Scene *scene, Object *camera, const ch
if (!is_multiview) {
return camera;
}
- else if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
+ if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
return camera;
}
- else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
- const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname);
- return camera_multiview_advanced(scene, camera, suffix);
- }
+ /* SCE_VIEWS_FORMAT_MULTIVIEW */
+ const char *suffix = BKE_scene_multiview_view_suffix_get(&scene->r, viewname);
+ return camera_multiview_advanced(scene, camera, suffix);
}
static float camera_stereo3d_shift_x(const Object *camera, const char *viewname)
@@ -1044,12 +1039,11 @@ float BKE_camera_multiview_shift_x(const RenderData *rd,
if (!is_multiview) {
return data->shiftx;
}
- else if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
+ if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) {
return data->shiftx;
}
- else { /* SCE_VIEWS_SETUP_BASIC */
- return camera_stereo3d_shift_x(camera, viewname);
- }
+ /* SCE_VIEWS_SETUP_BASIC */
+ return camera_stereo3d_shift_x(camera, viewname);
}
void BKE_camera_multiview_params(const RenderData *rd,
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 467bd68c631..027761335b0 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -825,7 +825,7 @@ static int cloth_from_object(
MVert *mvert = NULL;
ClothVertex *verts = NULL;
float(*shapekey_rest)[3] = NULL;
- float tnull[3] = {0, 0, 0};
+ const float tnull[3] = {0, 0, 0};
// If we have a clothObject, free it.
if (clmd->clothObject != NULL) {
@@ -1355,7 +1355,7 @@ BLI_INLINE void cross_identity_v3(float r[3][3], const float v[3])
r[2][1] = -v[0];
}
-BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f)
+BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
{
r[0][0] += m[0][0] * f;
r[0][1] += m[0][1] * f;
diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c
index 6118325c231..6d2432f53e4 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -540,9 +540,8 @@ const char *BKE_collection_ui_name_get(struct Collection *collection)
if (collection->flag & COLLECTION_IS_MASTER) {
return IFACE_("Scene Collection");
}
- else {
- return collection->id.name + 2;
- }
+
+ return collection->id.name + 2;
}
/** \} */
@@ -617,9 +616,8 @@ Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *c
if (collection) {
return BKE_collection_object_cache_get(collection).first;
}
- else {
- return FIRSTBASE(view_layer);
- }
+
+ return FIRSTBASE(view_layer);
}
/** \} */
@@ -671,14 +669,13 @@ static bool collection_object_cyclic_check_internal(Object *object, Collection *
if (dup_collection == collection) {
return true;
}
- else {
- FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (dup_collection, collection_object) {
- if (collection_object_cyclic_check_internal(collection_object, dup_collection)) {
- return true;
- }
+
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (dup_collection, collection_object) {
+ if (collection_object_cyclic_check_internal(collection_object, dup_collection)) {
+ return true;
}
- FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
/* un-flag the object, it's allowed to have the same collection multiple times in parallel */
dup_collection->id.tag |= LIB_TAG_DOIT;
@@ -725,9 +722,8 @@ static Collection *collection_next_find(Main *bmain, Scene *scene, Collection *c
if (scene && collection == scene->master_collection) {
return bmain->collections.first;
}
- else {
- return collection->id.next;
- }
+
+ return collection->id.next;
}
Collection *BKE_collection_object_find(Main *bmain,
@@ -1510,9 +1506,8 @@ bool BKE_collection_objects_select(ViewLayer *view_layer, Collection *collection
if (layer_collection != NULL) {
return BKE_layer_collection_objects_select(view_layer, layer_collection, deselect);
}
- else {
- return collection_objects_select(view_layer, collection, deselect);
- }
+
+ return collection_objects_select(view_layer, collection, deselect);
}
/** \} */
diff --git a/source/blender/blenkernel/intern/colorband.c b/source/blender/blenkernel/intern/colorband.c
index 499b0305c9d..323a2f0cf53 100644
--- a/source/blender/blenkernel/intern/colorband.c
+++ b/source/blender/blenkernel/intern/colorband.c
@@ -587,7 +587,7 @@ static int vergcband(const void *a1, const void *a2)
if (x1->pos > x2->pos) {
return 1;
}
- else if (x1->pos < x2->pos) {
+ if (x1->pos < x2->pos) {
return -1;
}
return 0;
@@ -620,18 +620,17 @@ CBData *BKE_colorband_element_add(struct ColorBand *coba, float position)
if (coba->tot == MAXCOLORBAND) {
return NULL;
}
- else {
- CBData *xnew;
- xnew = &coba->data[coba->tot];
- xnew->pos = position;
+ CBData *xnew;
- if (coba->tot != 0) {
- BKE_colorband_evaluate(coba, position, &xnew->r);
- }
- else {
- zero_v4(&xnew->r);
- }
+ xnew = &coba->data[coba->tot];
+ xnew->pos = position;
+
+ if (coba->tot != 0) {
+ BKE_colorband_evaluate(coba, position, &xnew->r);
+ }
+ else {
+ zero_v4(&xnew->r);
}
coba->tot++;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 4f4eb8f9f9d..11928dada2b 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -603,28 +603,24 @@ static float curvemap_calc_extend(const CurveMapping *cumap,
/* extrapolate horizontally */
return first[1];
}
- else {
- if (cuma->ext_in[0] == 0.0f) {
- return first[1] + cuma->ext_in[1] * 10000.0f;
- }
- else {
- return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0];
- }
+
+ if (cuma->ext_in[0] == 0.0f) {
+ return first[1] + cuma->ext_in[1] * 10000.0f;
}
+
+ return first[1] + cuma->ext_in[1] * (x - first[0]) / cuma->ext_in[0];
}
- else if (x >= last[0]) {
+ if (x >= last[0]) {
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
/* extrapolate horizontally */
return last[1];
}
- else {
- if (cuma->ext_out[0] == 0.0f) {
- return last[1] - cuma->ext_out[1] * 10000.0f;
- }
- else {
- return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0];
- }
+
+ if (cuma->ext_out[0] == 0.0f) {
+ return last[1] - cuma->ext_out[1] * 10000.0f;
}
+
+ return last[1] + cuma->ext_out[1] * (x - last[0]) / cuma->ext_out[0];
}
return 0.0f;
}
@@ -870,7 +866,7 @@ static int sort_curvepoints(const void *a1, const void *a2)
if (x1->x > x2->x) {
return 1;
}
- else if (x1->x < x2->x) {
+ if (x1->x < x2->x) {
return -1;
}
return 0;
@@ -984,17 +980,16 @@ float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, fl
if (fi < 0.0f || fi > CM_TABLE) {
return curvemap_calc_extend(cumap, cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
}
- else {
- if (i < 0) {
- return cuma->table[0].y;
- }
- if (i >= CM_TABLE) {
- return cuma->table[CM_TABLE].y;
- }
- fi = fi - (float)i;
- return (1.0f - fi) * cuma->table[i].y + (fi)*cuma->table[i + 1].y;
+ if (i < 0) {
+ return cuma->table[0].y;
}
+ if (i >= CM_TABLE) {
+ return cuma->table[CM_TABLE].y;
+ }
+
+ fi = fi - (float)i;
+ return (1.0f - fi) * cuma->table[i].y + (fi)*cuma->table[i + 1].y;
}
/* works with curve 'cur' */
@@ -1202,7 +1197,7 @@ int BKE_curvemapping_RGBA_does_something(const CurveMapping *cumap)
return 0;
}
-void BKE_curvemapping_initialize(CurveMapping *cumap)
+void BKE_curvemapping_init(CurveMapping *cumap)
{
int a;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 2ef32895db9..87d1b2561a9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2404,7 +2404,7 @@ static void armdef_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
}
}
-static void armdef_accumulate_matrix(float obmat[4][4],
+static void armdef_accumulate_matrix(const float obmat[4][4],
const float iobmat[4][4],
const float basemat[4][4],
const float bonemat[4][4],
@@ -5284,9 +5284,8 @@ const bConstraintTypeInfo *BKE_constraint_typeinfo_from_type(int type)
/* there shouldn't be any segfaults here... */
return constraintsTypeInfo[type];
}
- else {
- CLOG_WARN(&LOG, "No valid constraint type-info data available. Type = %i", type);
- }
+
+ CLOG_WARN(&LOG, "No valid constraint type-info data available. Type = %i", type);
return NULL;
}
@@ -5300,9 +5299,8 @@ const bConstraintTypeInfo *BKE_constraint_typeinfo_get(bConstraint *con)
if (con) {
return BKE_constraint_typeinfo_from_type(con->type);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* ************************* General Constraints API ************************** */
@@ -5384,9 +5382,8 @@ bool BKE_constraint_remove(ListBase *list, bConstraint *con)
BLI_freelinkN(list, con);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool clear_dep)
@@ -5399,9 +5396,8 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool
}
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/* ......... */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 30f021b0e81..e9ba3a5f873 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -255,13 +255,12 @@ static void *ctx_wm_python_context_get(const bContext *C,
if (RNA_struct_is_a(result.ptr.type, member_type)) {
return result.ptr.data;
}
- else {
- CLOG_WARN(&LOG,
- "PyContext '%s' is a '%s', expected a '%s'",
- member,
- RNA_struct_identifier(result.ptr.type),
- RNA_struct_identifier(member_type));
- }
+
+ CLOG_WARN(&LOG,
+ "PyContext '%s' is a '%s', expected a '%s'",
+ member,
+ RNA_struct_identifier(result.ptr.type),
+ RNA_struct_identifier(member_type));
}
}
#else
@@ -360,9 +359,8 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member)
BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr.data;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
@@ -374,15 +372,14 @@ static int ctx_data_pointer_verify(const bContext *C, const char *member, void *
*pointer = NULL;
return 1;
}
- else if (ctx_data_get((bContext *)C, member, &result) == 1) {
+ if (ctx_data_get((bContext *)C, member, &result) == 1) {
BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
*pointer = result.ptr.data;
return 1;
}
- else {
- *pointer = NULL;
- return 0;
- }
+
+ *pointer = NULL;
+ return 0;
}
static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
@@ -441,9 +438,8 @@ PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
return result.ptr;
}
- else {
- return PointerRNA_NULL;
- }
+
+ return PointerRNA_NULL;
}
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
@@ -454,13 +450,12 @@ PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, Stru
if (RNA_struct_is_a(ptr.type, type)) {
return ptr;
}
- else {
- CLOG_WARN(&LOG,
- "member '%s' is '%s', not '%s'",
- member,
- RNA_struct_identifier(ptr.type),
- RNA_struct_identifier(type));
- }
+
+ CLOG_WARN(&LOG,
+ "member '%s' is '%s', not '%s'",
+ member,
+ RNA_struct_identifier(ptr.type),
+ RNA_struct_identifier(type));
}
return PointerRNA_NULL;
@@ -473,9 +468,8 @@ PointerRNA CTX_data_pointer_get_type_silent(const bContext *C, const char *membe
if (ptr.data && RNA_struct_is_a(ptr.type, type)) {
return ptr;
}
- else {
- return PointerRNA_NULL;
- }
+
+ return PointerRNA_NULL;
}
ListBase CTX_data_collection_get(const bContext *C, const char *member)
@@ -486,10 +480,9 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member)
BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
return result.list;
}
- else {
- ListBase list = {NULL, NULL};
- return list;
- }
+
+ ListBase list = {NULL, NULL};
+ return list;
}
/* 1:found, -1:found but not set, 0:not found */
@@ -667,9 +660,8 @@ int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBas
BLI_freelistN(&list);
return tot;
}
- else {
- return 0;
- }
+
+ return 0;
}
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
@@ -985,9 +977,8 @@ Main *CTX_data_main(const bContext *C)
if (ctx_data_pointer_verify(C, "blend_data", (void *)&bmain)) {
return bmain;
}
- else {
- return C->data.main;
- }
+
+ return C->data.main;
}
void CTX_data_main_set(bContext *C, Main *bmain)
@@ -1003,9 +994,8 @@ Scene *CTX_data_scene(const bContext *C)
if (ctx_data_pointer_verify(C, "scene", (void *)&scene)) {
return scene;
}
- else {
- return C->data.scene;
- }
+
+ return C->data.scene;
}
ViewLayer *CTX_data_view_layer(const bContext *C)
@@ -1102,34 +1092,34 @@ enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit,
if (object_mode & OB_MODE_POSE) {
return CTX_MODE_POSE;
}
- else if (object_mode & OB_MODE_SCULPT) {
+ if (object_mode & OB_MODE_SCULPT) {
return CTX_MODE_SCULPT;
}
- else if (object_mode & OB_MODE_WEIGHT_PAINT) {
+ if (object_mode & OB_MODE_WEIGHT_PAINT) {
return CTX_MODE_PAINT_WEIGHT;
}
- else if (object_mode & OB_MODE_VERTEX_PAINT) {
+ if (object_mode & OB_MODE_VERTEX_PAINT) {
return CTX_MODE_PAINT_VERTEX;
}
- else if (object_mode & OB_MODE_TEXTURE_PAINT) {
+ if (object_mode & OB_MODE_TEXTURE_PAINT) {
return CTX_MODE_PAINT_TEXTURE;
}
- else if (object_mode & OB_MODE_PARTICLE_EDIT) {
+ if (object_mode & OB_MODE_PARTICLE_EDIT) {
return CTX_MODE_PARTICLE;
}
- else if (object_mode & OB_MODE_PAINT_GPENCIL) {
+ if (object_mode & OB_MODE_PAINT_GPENCIL) {
return CTX_MODE_PAINT_GPENCIL;
}
- else if (object_mode & OB_MODE_EDIT_GPENCIL) {
+ if (object_mode & OB_MODE_EDIT_GPENCIL) {
return CTX_MODE_EDIT_GPENCIL;
}
- else if (object_mode & OB_MODE_SCULPT_GPENCIL) {
+ if (object_mode & OB_MODE_SCULPT_GPENCIL) {
return CTX_MODE_SCULPT_GPENCIL;
}
- else if (object_mode & OB_MODE_WEIGHT_GPENCIL) {
+ if (object_mode & OB_MODE_WEIGHT_GPENCIL) {
return CTX_MODE_WEIGHT_GPENCIL;
}
- else if (object_mode & OB_MODE_VERTEX_GPENCIL) {
+ if (object_mode & OB_MODE_VERTEX_GPENCIL) {
return CTX_MODE_VERTEX_GPENCIL;
}
}
@@ -1173,9 +1163,8 @@ ToolSettings *CTX_data_tool_settings(const bContext *C)
if (scene) {
return scene->toolsettings;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
int CTX_data_selected_nodes(const bContext *C, ListBase *list)
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 0627d2005d5..8e03f61d601 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -223,7 +223,7 @@ void BKE_curve_init(Curve *cu, const short curve_type)
cu->vfont->id.us += 4;
cu->str = MEM_malloc_arrayN(12, sizeof(unsigned char), "str");
BLI_strncpy(cu->str, "Text", 12);
- cu->len = cu->len_wchar = cu->pos = 4;
+ cu->len = cu->len_char32 = cu->pos = 4;
cu->strinfo = MEM_calloc_arrayN(12, sizeof(CharInfo), "strinfo new");
cu->totbox = cu->actbox = 1;
cu->tb = MEM_calloc_arrayN(MAXTEXTBOX, sizeof(TextBox), "textbox");
@@ -1726,205 +1726,6 @@ static void forward_diff_bezier_cotangent(const float p0[3],
}
}
-/* ***************** BEVEL ****************** */
-
-void BKE_curve_bevel_make(Object *ob, ListBase *disp)
-{
- DispList *dl, *dlnew;
- Curve *bevcu, *cu;
- float *fp, facx, facy, angle, dangle;
- int nr, a;
-
- cu = ob->data;
- BLI_listbase_clear(disp);
-
- /* if a font object is being edited, then do nothing */
- // XXX if ( ob == obedit && ob->type == OB_FONT ) return;
-
- if (cu->bevobj) {
- if (cu->bevobj->type != OB_CURVE) {
- return;
- }
-
- bevcu = cu->bevobj->data;
- if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
- ListBase bevdisp = {NULL, NULL};
- facx = cu->bevobj->scale[0];
- facy = cu->bevobj->scale[1];
-
- if (cu->bevobj->runtime.curve_cache) {
- dl = cu->bevobj->runtime.curve_cache->disp.first;
- }
- else {
- BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
- dl = NULL;
- }
-
- while (dl) {
- if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
- dlnew = MEM_mallocN(sizeof(DispList), "makebevelcurve1");
- *dlnew = *dl;
- dlnew->verts = MEM_malloc_arrayN(
- dl->parts * dl->nr, 3 * sizeof(float), "makebevelcurve1");
- memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
-
- if (dlnew->type == DL_SEGM) {
- dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
- }
-
- BLI_addtail(disp, dlnew);
- fp = dlnew->verts;
- nr = dlnew->parts * dlnew->nr;
- while (nr--) {
- fp[2] = fp[1] * facy;
- fp[1] = -fp[0] * facx;
- fp[0] = 0.0;
- fp += 3;
- }
- }
- dl = dl->next;
- }
-
- BKE_displist_free(&bevdisp);
- }
- }
- else if (cu->ext1 == 0.0f && cu->ext2 == 0.0f) {
- /* pass */
- }
- else if (cu->ext2 == 0.0f) {
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve2");
- dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), "makebevelcurve2");
- BLI_addtail(disp, dl);
- dl->type = DL_SEGM;
- dl->parts = 1;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- dl->nr = 2;
-
- fp = dl->verts;
- fp[0] = fp[1] = 0.0;
- fp[2] = -cu->ext1;
- fp[3] = fp[4] = 0.0;
- fp[5] = cu->ext1;
- }
- else if ((cu->flag & (CU_FRONT | CU_BACK)) == 0 && cu->ext1 == 0.0f) {
- /* We make a full round bevel in that case. */
-
- nr = 4 + 2 * cu->bevresol;
-
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve p1");
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve p1");
- BLI_addtail(disp, dl);
- dl->type = DL_POLY;
- dl->parts = 1;
- dl->flag = DL_BACK_CURVE;
- dl->nr = nr;
-
- /* a circle */
- fp = dl->verts;
- dangle = (2.0f * (float)M_PI / (nr));
- angle = -(nr - 1) * dangle;
-
- for (a = 0; a < nr; a++) {
- fp[0] = 0.0;
- fp[1] = (cosf(angle) * (cu->ext2));
- fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- else {
- /* The general case for nonzero extrusion or an incomplete loop. */
- dl = MEM_callocN(sizeof(DispList), "makebevelcurve");
- if ((cu->flag & (CU_FRONT | CU_BACK)) == 0) {
- /* The full loop. */
- nr = 4 * cu->bevresol + 6;
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else if ((cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Half the loop. */
- nr = 2 * (cu->bevresol + 1) + ((cu->ext1 == 0.0f) ? 1 : 2);
- dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
- }
- else {
- /* One quarter of the loop (just front or back). */
- nr = (cu->ext1 == 0.0f) ? cu->bevresol + 2 : cu->bevresol + 3;
- dl->flag = (cu->flag & CU_FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
- }
-
- dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), "makebevelcurve");
- BLI_addtail(disp, dl);
- /* Use a different type depending on whether the loop is complete or not. */
- dl->type = ((cu->flag & (CU_FRONT | CU_BACK)) == 0) ? DL_POLY : DL_SEGM;
- dl->parts = 1;
- dl->nr = nr;
-
- fp = dl->verts;
- dangle = (float)M_PI_2 / (cu->bevresol + 1);
- angle = 0.0;
-
- /* Build the back section. */
- if (cu->flag & CU_BACK || !(cu->flag & CU_FRONT)) {
- angle = (float)M_PI_2 * 3.0f;
- for (a = 0; a < cu->bevresol + 2; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_FRONT) && (cu->flag & CU_BACK)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = cu->ext1;
- }
- }
-
- /* Build the front section. */
- if (cu->flag & CU_FRONT || !(cu->flag & CU_BACK)) {
- if ((cu->ext1 != 0.0f) && !(cu->flag & CU_BACK) && (cu->flag & CU_FRONT)) {
- /* Add the extrusion if we're only building the back. */
- fp[0] = 0.0;
- fp[1] = cu->ext2;
- fp[2] = -cu->ext1;
- fp += 3;
- }
- /* Don't duplicate the last back vertex. */
- angle = (cu->ext1 == 0.0f && (cu->flag & CU_BACK)) ? dangle : 0;
- int front_len = (cu->ext1 == 0.0f && ((cu->flag & CU_BACK) || !(cu->flag & CU_FRONT))) ?
- cu->bevresol + 1 :
- cu->bevresol + 2;
- for (a = 0; a < front_len; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
-
- /* Build the other half only if we're building the full loop. */
- if (!(cu->flag & (CU_FRONT | CU_BACK))) {
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
- angle += dangle;
- fp += 3;
- }
-
- angle = (float)M_PI;
- for (a = 0; a < cu->bevresol + 1; a++) {
- fp[0] = 0.0;
- fp[1] = (float)(cosf(angle) * (cu->ext2));
- fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
- angle += dangle;
- fp += 3;
- }
- }
- }
-}
-
static int cu_isectLL(const float v1[3],
const float v2[3],
const float v3[3],
@@ -2500,7 +2301,7 @@ static void make_bevel_list_3D_tangent(BevList *bl)
while (nr--) {
/* make perpendicular, modify tan in place, is ok */
float cross_tmp[3];
- float zero[3] = {0, 0, 0};
+ const float zero[3] = {0, 0, 0};
cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir);
normalize_v3(cross_tmp);
@@ -3797,7 +3598,10 @@ static void bezier_clamp(
}
/* write changes to a bezier handle */
-static void bezier_output_handle_inner(BezTriple *bezt, bool right, float newval[3], bool endpoint)
+static void bezier_output_handle_inner(BezTriple *bezt,
+ bool right,
+ const float newval[3],
+ bool endpoint)
{
float tmp[3];
@@ -5441,7 +5245,7 @@ void BKE_curve_material_index_remove(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr && info->mat_nr >= index) {
info->mat_nr--;
}
@@ -5465,7 +5269,7 @@ bool BKE_curve_material_index_used(Curve *cu, int index)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr == index) {
return true;
}
@@ -5491,7 +5295,7 @@ void BKE_curve_material_index_clear(Curve *cu)
if (curvetype == OB_FONT) {
struct CharInfo *info = cu->strinfo;
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
info->mat_nr = 0;
}
}
@@ -5513,7 +5317,7 @@ bool BKE_curve_material_index_validate(Curve *cu)
CharInfo *info = cu->strinfo;
const int max_idx = max_ii(0, cu->totcol); /* OB_FONT use 1 as first mat index, not 0!!! */
int i;
- for (i = cu->len_wchar - 1; i >= 0; i--, info++) {
+ for (i = cu->len_char32 - 1; i >= 0; i--, info++) {
if (info->mat_nr > max_idx) {
info->mat_nr = 0;
is_valid = false;
@@ -5561,7 +5365,7 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int
}
else {
strinfo = cu->strinfo;
- charinfo_len = cu->len_wchar;
+ charinfo_len = cu->len_char32;
}
for (i = 0; i <= charinfo_len; i++) {
diff --git a/source/blender/blenkernel/intern/curve_bevel.c b/source/blender/blenkernel/intern/curve_bevel.c
new file mode 100644
index 00000000000..7f23f0215cc
--- /dev/null
+++ b/source/blender/blenkernel/intern/curve_bevel.c
@@ -0,0 +1,272 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bke
+ *
+ * Handle curve object data bevel options,
+ * both extruding
+ */
+
+#include <string.h>
+
+#include "BLI_listbase.h"
+#include "BLI_math_base.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_curve_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_curve.h"
+#include "BKE_displist.h"
+
+typedef enum CurveBevelFillType {
+ BACK = 0,
+ FRONT,
+ HALF,
+ FULL,
+} CurveBevelFillType;
+
+static CurveBevelFillType curve_bevel_get_fill_type(const Curve *curve)
+{
+ if (!(curve->flag & (CU_FRONT | CU_BACK))) {
+ return FULL;
+ }
+ if ((curve->flag & CU_FRONT) && (curve->flag & CU_BACK)) {
+ return HALF;
+ }
+
+ return (curve->flag & CU_FRONT) ? FRONT : BACK;
+}
+
+static void curve_bevel_make_extrude_and_fill(Curve *cu,
+ ListBase *disp,
+ const bool use_extrude,
+ const CurveBevelFillType fill_type)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+
+ int nr;
+ if (fill_type == FULL) {
+ /* The full loop. */
+ nr = 4 * cu->bevresol + 6;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else if (fill_type == HALF) {
+ /* Half the loop. */
+ nr = 2 * (cu->bevresol + 1) + (use_extrude ? 2 : 1);
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ }
+ else {
+ /* One quarter of the loop (just front or back). */
+ nr = use_extrude ? cu->bevresol + 3 : cu->bevresol + 2;
+ dl->flag = (fill_type == FRONT) ? DL_FRONT_CURVE : DL_BACK_CURVE;
+ }
+
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ /* Use a different type depending on whether the loop is complete or not. */
+ dl->type = (fill_type == FULL) ? DL_POLY : DL_SEGM;
+ dl->parts = 1;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (float)M_PI_2 / (cu->bevresol + 1);
+ float angle = 0.0f;
+
+ /* Build the back section. */
+ if (ELEM(fill_type, BACK, HALF, FULL)) {
+ angle = (float)M_PI_2 * 3.0f;
+ for (int i = 0; i < cu->bevresol + 2; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ if (use_extrude && fill_type == BACK) {
+ /* Add the extrusion if we're only building the back. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = cu->ext1;
+ }
+ }
+
+ /* Build the front section. */
+ if (ELEM(fill_type, FRONT, HALF, FULL)) {
+ if (use_extrude && fill_type == FRONT) {
+ /* Add the extrusion if we're only building the front. */
+ fp[0] = 0.0f;
+ fp[1] = cu->ext2;
+ fp[2] = -cu->ext1;
+ fp += 3;
+ }
+ /* Don't duplicate the last back vertex. */
+ angle = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? dangle : 0;
+ int front_len = (!use_extrude && ELEM(fill_type, HALF, FULL)) ? cu->bevresol + 1 :
+ cu->bevresol + 2;
+ for (int i = 0; i < front_len; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+
+ /* Build the other half only if we're building the full loop. */
+ if (fill_type == FULL) {
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) + cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+
+ angle = (float)M_PI;
+ for (int i = 0; i < cu->bevresol + 1; i++) {
+ fp[0] = 0.0f;
+ fp[1] = (float)(cosf(angle) * (cu->ext2));
+ fp[2] = (float)(sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+ }
+}
+
+static void curve_bevel_make_full_circle(Curve *cu, ListBase *disp)
+{
+ const int nr = 4 + 2 * cu->bevresol;
+
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(nr, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_POLY;
+ dl->parts = 1;
+ dl->flag = DL_BACK_CURVE;
+ dl->nr = nr;
+
+ float *fp = dl->verts;
+ const float dangle = (2.0f * (float)M_PI / (nr));
+ float angle = -(nr - 1) * dangle;
+
+ for (int i = 0; i < nr; i++) {
+ fp[0] = 0.0;
+ fp[1] = (cosf(angle) * (cu->ext2));
+ fp[2] = (sinf(angle) * (cu->ext2)) - cu->ext1;
+ angle += dangle;
+ fp += 3;
+ }
+}
+
+static void curve_bevel_make_only_extrude(Curve *cu, ListBase *disp)
+{
+ DispList *dl = MEM_callocN(sizeof(DispList), __func__);
+ dl->verts = MEM_malloc_arrayN(2, sizeof(float[3]), __func__);
+ BLI_addtail(disp, dl);
+ dl->type = DL_SEGM;
+ dl->parts = 1;
+ dl->flag = DL_FRONT_CURVE | DL_BACK_CURVE;
+ dl->nr = 2;
+
+ float *fp = dl->verts;
+ fp[0] = fp[1] = 0.0;
+ fp[2] = -cu->ext1;
+ fp[3] = fp[4] = 0.0;
+ fp[5] = cu->ext1;
+}
+
+static void curve_bevel_make_from_object(Curve *cu, ListBase *disp)
+{
+ if (cu->bevobj->type != OB_CURVE) {
+ return;
+ }
+
+ Curve *bevcu = cu->bevobj->data;
+ if (bevcu->ext1 == 0.0f && bevcu->ext2 == 0.0f) {
+ ListBase bevdisp = {NULL, NULL};
+ float facx = cu->bevobj->scale[0];
+ float facy = cu->bevobj->scale[1];
+
+ DispList *dl;
+ if (cu->bevobj->runtime.curve_cache) {
+ dl = cu->bevobj->runtime.curve_cache->disp.first;
+ }
+ else {
+ BLI_assert(cu->bevobj->runtime.curve_cache != NULL);
+ dl = NULL;
+ }
+
+ while (dl) {
+ if (ELEM(dl->type, DL_POLY, DL_SEGM)) {
+ DispList *dlnew = MEM_mallocN(sizeof(DispList), __func__);
+ *dlnew = *dl;
+ dlnew->verts = MEM_malloc_arrayN(dl->parts * dl->nr, 3 * sizeof(float), __func__);
+ memcpy(dlnew->verts, dl->verts, 3 * sizeof(float) * dl->parts * dl->nr);
+
+ if (dlnew->type == DL_SEGM) {
+ dlnew->flag |= (DL_FRONT_CURVE | DL_BACK_CURVE);
+ }
+
+ BLI_addtail(disp, dlnew);
+ float *fp = dlnew->verts;
+ int nr = dlnew->parts * dlnew->nr;
+ while (nr--) {
+ fp[2] = fp[1] * facy;
+ fp[1] = -fp[0] * facx;
+ fp[0] = 0.0;
+ fp += 3;
+ }
+ }
+ dl = dl->next;
+ }
+
+ BKE_displist_free(&bevdisp);
+ }
+}
+
+void BKE_curve_bevel_make(Object *ob, ListBase *disp)
+{
+ Curve *curve = ob->data;
+
+ const bool use_extrude = curve->ext1 != 0.0f;
+ const bool use_bevel = curve->ext2 != 0.0f;
+
+ BLI_listbase_clear(disp);
+
+ if (curve->bevobj) {
+ curve_bevel_make_from_object(curve, disp);
+ }
+ else if (!(use_extrude || use_bevel)) {
+ /* Pass. */
+ }
+ else if (use_extrude && !use_bevel) {
+ curve_bevel_make_only_extrude(curve, disp);
+ }
+ else {
+ CurveBevelFillType fill_type = curve_bevel_get_fill_type(curve);
+
+ if (!use_extrude && fill_type == FULL) {
+ curve_bevel_make_full_circle(curve, disp);
+ }
+ else {
+ /* The general case for nonzero extrusion or an incomplete loop. */
+ curve_bevel_make_extrude_and_fill(curve, disp, use_extrude, fill_type);
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/curveprofile.c b/source/blender/blenkernel/intern/curveprofile.c
index 6919d4fa10f..068f8845e64 100644
--- a/source/blender/blenkernel/intern/curveprofile.c
+++ b/source/blender/blenkernel/intern/curveprofile.c
@@ -254,7 +254,7 @@ void BKE_curveprofile_remove_by_flag(CurveProfile *profile, const short flag)
CurveProfilePoint *BKE_curveprofile_insert(CurveProfile *profile, float x, float y)
{
CurveProfilePoint *new_pt = NULL;
- float new_loc[2] = {x, y};
+ const float new_loc[2] = {x, y};
/* Don't add more control points than the maximum size of the higher resolution table. */
if (profile->path_len == PROF_TABLE_MAX - 1) {
@@ -266,8 +266,8 @@ CurveProfilePoint *BKE_curveprofile_insert(CurveProfile *profile, float x, float
float min_distance = FLT_MAX;
int i_insert = 0;
for (int i = 0; i < profile->path_len - 1; i++) {
- float loc1[2] = {profile->path[i].x, profile->path[i].y};
- float loc2[2] = {profile->path[i + 1].x, profile->path[i + 1].y};
+ const float loc1[2] = {profile->path[i].x, profile->path[i].y};
+ const float loc2[2] = {profile->path[i + 1].x, profile->path[i + 1].y};
distance = dist_squared_to_line_segment_v2(new_loc, loc1, loc2);
if (distance < min_distance) {
@@ -689,9 +689,8 @@ static int sort_points_curvature(const void *in_a, const void *in_b)
if (a->bezt_curvature > b->bezt_curvature) {
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
/**
@@ -886,7 +885,7 @@ void BKE_curveprofile_create_samples(CurveProfile *profile,
*/
static void curveprofile_make_table(CurveProfile *profile)
{
- int n_samples = PROF_N_TABLE(profile->path_len);
+ int n_samples = PROF_TABLE_LEN(profile->path_len);
CurveProfilePoint *new_table = MEM_callocN(sizeof(CurveProfilePoint) * (n_samples + 1),
"high-res table");
@@ -1040,7 +1039,7 @@ void BKE_curveprofile_update(CurveProfile *profile, const int update_flags)
* Also sets the number of segments used for the display preview of the locations
* of the sampled points.
*/
-void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
+void BKE_curveprofile_init(CurveProfile *profile, short segments_len)
{
if (segments_len != profile->segments_len) {
profile->flag |= PROF_DIRTY_PRESET;
@@ -1055,11 +1054,11 @@ void BKE_curveprofile_initialize(CurveProfile *profile, short segments_len)
* Gives the distance to the next point in the widgets sampled table, in other words the length
* of the \a 'i' edge of the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
static float curveprofile_distance_to_next_table_point(const CurveProfile *profile, int i)
{
- BLI_assert(i < PROF_N_TABLE(profile->path_len));
+ BLI_assert(i < PROF_TABLE_LEN(profile->path_len));
return len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
@@ -1067,12 +1066,12 @@ static float curveprofile_distance_to_next_table_point(const CurveProfile *profi
/**
* Calculates the total length of the profile from the curves sampled in the table.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
float BKE_curveprofile_total_length(const CurveProfile *profile)
{
float total_length = 0;
- for (int i = 0; i < PROF_N_TABLE(profile->path_len) - 1; i++) {
+ for (int i = 0; i < PROF_TABLE_LEN(profile->path_len) - 1; i++) {
total_length += len_v2v2(&profile->table[i].x, &profile->table[i + 1].x);
}
return total_length;
@@ -1082,7 +1081,7 @@ float BKE_curveprofile_total_length(const CurveProfile *profile)
* Samples evenly spaced positions along the curve profile's table (generated from path). Fills
* an entire table at once for a speedup if all of the results are going to be used anyway.
*
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
* \note Working, but would conflict with "Sample Straight Edges" option, so this is unused for
* now.
*/
@@ -1145,7 +1144,7 @@ void BKE_curveprofile_create_samples_even_spacing(CurveProfile *profile,
* Travels down (length_portion * path) length and returns the position at that point.
*
* \param length_portion: The portion (0 to 1) of the path's full length to sample at.
- * \note Requires curveprofile_initialize or #BKE_curveprofile_update call before to fill table.
+ * \note Requires #BKE_curveprofile_init or #BKE_curveprofile_update call before to fill table.
*/
void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_portion,
@@ -1160,7 +1159,7 @@ void BKE_curveprofile_evaluate_length_portion(const CurveProfile *profile,
float length_travelled = 0.0f;
while (length_travelled < requested_length) {
/* Check if we reached the last point before the final one. */
- if (i == PROF_N_TABLE(profile->path_len) - 2) {
+ if (i == PROF_TABLE_LEN(profile->path_len) - 2) {
break;
}
float new_length = curveprofile_distance_to_next_table_point(profile, i);
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 707db46a856..0c1717ea184 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -771,7 +771,7 @@ static void layerCopyValue_mloopcol(const void *source,
if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
return; /* Do Nothing! */
}
- else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
+ if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
return; /* Do Nothing! */
}
}
@@ -1358,7 +1358,7 @@ static void layerCopyValue_propcol(const void *source,
if (mixmode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && f < mixfactor) {
return; /* Do Nothing! */
}
- else if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
+ if (mixmode == CDT_MIX_REPLACE_BELOW_THRESHOLD && f > mixfactor) {
return; /* Do Nothing! */
}
}
@@ -2201,13 +2201,13 @@ bool CustomData_merge(const struct CustomData *source,
if (flag & CD_FLAG_NOCOPY) {
continue;
}
- else if (!(mask & CD_TYPE_AS_MASK(type))) {
+ if (!(mask & CD_TYPE_AS_MASK(type))) {
continue;
}
- else if ((maxnumber != -1) && (number >= maxnumber)) {
+ if ((maxnumber != -1) && (number >= maxnumber)) {
continue;
}
- else if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) {
+ if (CustomData_get_named_layer_index(dest, type, layer->name) != -1) {
continue;
}
@@ -2643,11 +2643,13 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
}
if (alloctype == CD_DUPLICATE && layerdata) {
- if (typeInfo->copy) {
- typeInfo->copy(layerdata, newlayerdata, totelem);
- }
- else {
- memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ if (totelem > 0) {
+ if (typeInfo->copy) {
+ typeInfo->copy(layerdata, newlayerdata, totelem);
+ }
+ else {
+ memcpy(newlayerdata, layerdata, (size_t)totelem * typeInfo->size);
+ }
}
}
else if (alloctype == CD_DEFAULT) {
@@ -4050,9 +4052,8 @@ bool CustomData_data_equals(int type, const void *data1, const void *data2)
if (typeInfo->equal) {
return typeInfo->equal(data1, data2);
}
- else {
- return !memcmp(data1, data2, typeInfo->size);
- }
+
+ return !memcmp(data1, data2, typeInfo->size);
}
void CustomData_data_initminmax(int type, void *min, void *max)
@@ -4409,7 +4410,7 @@ int CustomData_layertype_layers_max(const int type)
if (typeInfo->defaultname == NULL) {
return 1;
}
- else if (typeInfo->layers_max == NULL) {
+ if (typeInfo->layers_max == NULL) {
return -1;
}
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index 1463e50f6e3..4fa232a368b 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -101,9 +101,8 @@ static int cdf_endian(void)
if (ENDIAN_ORDER == L_ENDIAN) {
return CDF_ENDIAN_LITTLE;
}
- else {
- return CDF_ENDIAN_BIG;
- }
+
+ return CDF_ENDIAN_BIG;
}
CDataFile *cdf_create(int type)
@@ -318,9 +317,8 @@ bool cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
if (&cdf->layer[a] == blay) {
break;
}
- else {
- offset += cdf->layer[a].datasize;
- }
+
+ offset += cdf->layer[a].datasize;
}
return (fseek(cdf->readf, offset, SEEK_SET) == 0);
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 7bf87d0e639..179f2f44180 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -961,7 +961,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (cddata_type == CD_FAKE_BWEIGHT) {
+ if (cddata_type == CD_FAKE_BWEIGHT) {
const size_t elem_size = sizeof(*((MVert *)NULL));
const size_t data_size = sizeof(((MVert *)NULL)->bweight);
const size_t data_offset = offsetof(MVert, bweight);
@@ -993,7 +993,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (cddata_type == CD_FAKE_MDEFORMVERT) {
+ if (cddata_type == CD_FAKE_MDEFORMVERT) {
bool ret;
cd_src = &me_src->vdata;
@@ -1018,7 +1018,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
return ret;
}
- else if (cddata_type == CD_FAKE_SHAPEKEY) {
+ if (cddata_type == CD_FAKE_SHAPEKEY) {
/* TODO: leaving shapekeys aside for now, quite specific case,
* since we can't access them from MVert :/ */
return false;
@@ -1049,7 +1049,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (cddata_type == CD_FAKE_CREASE) {
+ if (cddata_type == CD_FAKE_CREASE) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->crease);
const size_t data_offset = offsetof(MEdge, crease);
@@ -1081,7 +1081,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (cddata_type == CD_FAKE_BWEIGHT) {
+ if (cddata_type == CD_FAKE_BWEIGHT) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->bweight);
const size_t data_offset = offsetof(MEdge, bweight);
@@ -1113,7 +1113,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
+ if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
const size_t elem_size = sizeof(*((MEdge *)NULL));
const size_t data_size = sizeof(((MEdge *)NULL)->flag);
const size_t data_offset = offsetof(MEdge, flag);
@@ -1136,9 +1136,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
interp_data);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
else if (elem_type == ME_LOOP) {
if (cddata_type == CD_FAKE_UV) {
@@ -1176,9 +1175,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else {
- return false;
- }
+
+ return false;
}
else if (elem_type == ME_POLY) {
if (cddata_type == CD_FAKE_UV) {
@@ -1209,7 +1207,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
return true;
}
- else if (r_map && cddata_type == CD_FAKE_SHARP) {
+ if (r_map && cddata_type == CD_FAKE_SHARP) {
const size_t elem_size = sizeof(*((MPoly *)NULL));
const size_t data_size = sizeof(((MPoly *)NULL)->flag);
const size_t data_offset = offsetof(MPoly, flag);
@@ -1232,9 +1230,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
interp_data);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
return false;
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 98fc5f9a23a..1a32deac776 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -510,36 +510,35 @@ int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const boo
if (defbase_tot == 0) {
return NULL;
}
- else {
- bDeformGroup *dg;
- char name_flip[sizeof(dg->name)];
- int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
- for (i = 0; i < defbase_tot; i++) {
- map[i] = -1;
- }
+ bDeformGroup *dg;
+ char name_flip[sizeof(dg->name)];
+ int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
- for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
- if (map[i] == -1) { /* may be calculated previously */
+ for (i = 0; i < defbase_tot; i++) {
+ map[i] = -1;
+ }
- /* in case no valid value is found, use this */
- if (use_default) {
- map[i] = i;
- }
+ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
+ if (map[i] == -1) { /* may be calculated previously */
- BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+ /* in case no valid value is found, use this */
+ if (use_default) {
+ map[i] = i;
+ }
- if (!STREQ(name_flip, dg->name)) {
- flip_num = BKE_object_defgroup_name_index(ob, name_flip);
- if (flip_num >= 0) {
- map[i] = flip_num;
- map[flip_num] = i; /* save an extra lookup */
- }
+ BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+
+ if (!STREQ(name_flip, dg->name)) {
+ flip_num = BKE_object_defgroup_name_index(ob, name_flip);
+ if (flip_num >= 0) {
+ map[i] = flip_num;
+ map[flip_num] = i; /* save an extra lookup */
}
}
}
- return map;
}
+ return map;
}
/**
@@ -555,29 +554,28 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob,
if (defbase_tot == 0) {
return NULL;
}
- else {
- bDeformGroup *dg;
- char name_flip[sizeof(dg->name)];
- int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
- for (i = 0; i < defbase_tot; i++) {
- map[i] = use_default ? i : -1;
- }
+ bDeformGroup *dg;
+ char name_flip[sizeof(dg->name)];
+ int i, flip_num, *map = MEM_mallocN(defbase_tot * sizeof(int), __func__);
- dg = BLI_findlink(&ob->defbase, defgroup);
+ for (i = 0; i < defbase_tot; i++) {
+ map[i] = use_default ? i : -1;
+ }
- BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
- if (!STREQ(name_flip, dg->name)) {
- flip_num = BKE_object_defgroup_name_index(ob, name_flip);
+ dg = BLI_findlink(&ob->defbase, defgroup);
- if (flip_num != -1) {
- map[defgroup] = flip_num;
- map[flip_num] = defgroup;
- }
- }
+ BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
+ if (!STREQ(name_flip, dg->name)) {
+ flip_num = BKE_object_defgroup_name_index(ob, name_flip);
- return map;
+ if (flip_num != -1) {
+ map[defgroup] = flip_num;
+ map[flip_num] = defgroup;
+ }
}
+
+ return map;
}
int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default)
@@ -658,7 +656,7 @@ float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert,
if (defgroup == -1) {
return 1.0f;
}
- else if (dvert == NULL) {
+ if (dvert == NULL) {
return 0.0f;
}
@@ -909,10 +907,9 @@ float BKE_defvert_calc_lock_relative_weight(float weight,
if (weight != 0.0f) {
return 1.0f;
}
- else {
- /* resolve 0/0 to 0 */
- return 0.0f;
- }
+
+ /* resolve 0/0 to 0 */
+ return 0.0f;
}
/* non-degenerate division */
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 7b7b7ceb84b..a39f2ccb6d8 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -320,7 +320,7 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
return 0; /* not supported atm */
}
- else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
+ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
const Mesh *canvas_mesh = dynamicPaint_canvas_mesh_get(surface->canvas);
return (canvas_mesh) ? canvas_mesh->totvert : 0;
}
@@ -353,7 +353,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object
Mesh *me = ob->data;
return (CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name) != -1);
}
- else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
+ if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
return (BKE_object_defgroup_name_index(ob, name) != -1);
}
}
@@ -602,7 +602,7 @@ static bool boundIntersectPoint(Bounds3D *b, const float point[3], const float r
}
/* expand bounds by a new point */
-static void boundInsert(Bounds3D *b, float point[3])
+static void boundInsert(Bounds3D *b, const float point[3])
{
if (!b->valid) {
copy_v3_v3(b->min, point);
@@ -2675,7 +2675,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
int w = bdata->w, h = bdata->h, px = bdata->px, py = bdata->py;
- int final_pixel[2] = {(int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h)};
+ const int final_pixel[2] = {(int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h)};
/* If current pixel uv is outside of texture */
if (final_pixel[0] < 0 || final_pixel[0] >= w || final_pixel[1] < 0 || final_pixel[1] >= h) {
@@ -3742,7 +3742,7 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1,
if (brush->collision == MOD_DPAINT_COL_VOLUME) {
return boundsIntersect(b1, b2);
}
- else if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) {
+ if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) {
return boundsIntersectDist(b1, b2, brush_radius);
}
return true;
diff --git a/source/blender/blenkernel/intern/editmesh_cache.c b/source/blender/blenkernel/intern/editmesh_cache.c
index 5017a48d14e..d0509c94fc6 100644
--- a/source/blender/blenkernel/intern/editmesh_cache.c
+++ b/source/blender/blenkernel/intern/editmesh_cache.c
@@ -148,11 +148,10 @@ bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
}
return true;
}
- else {
- zero_v3(min);
- zero_v3(max);
- return false;
- }
+
+ zero_v3(min);
+ zero_v3(max);
+ return false;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c
index 6fcaf84d4ca..897fc7e692b 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.c
+++ b/source/blender/blenkernel/intern/editmesh_tangent.c
@@ -274,8 +274,8 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict UNUSED(pool), vo
/**
* \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data.
*
- * \note This function is not so normal, its using `bm->ldata` as input,
- * but output's to `dm->loopData`.
+ * \note This function is not so normal, its using #BMesh.ldata as input,
+ * but output's to #Mesh.ldata.
* This is done because #CD_TANGENT is cache data used only for drawing.
*/
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index a43553ee89f..97f9cebf58b 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -313,10 +313,10 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
if (ob == ob_src) {
continue;
}
- else if (weights->weight[ob->pd->forcefield] == 0.0f) {
+ if (weights->weight[ob->pd->forcefield] == 0.0f) {
continue;
}
- else if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
+ if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
continue;
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index acbbf50701a..abed90e7192 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -320,7 +320,7 @@ int BKE_fcurves_filter(ListBase *dst, ListBase *src, const char *dataPrefix, con
if (ELEM(NULL, dst, src, dataPrefix, dataName)) {
return 0;
}
- else if ((dataPrefix[0] == 0) || (dataName[0] == 0)) {
+ if ((dataPrefix[0] == 0) || (dataName[0] == 0)) {
return 0;
}
@@ -915,7 +915,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, BezTriple *bezt)
return;
}
/* should key be inserted before this column? */
- else if (ce->cfra > bezt->vec[1][0]) {
+ if (ce->cfra > bezt->vec[1][0]) {
break;
}
}
diff --git a/source/blender/blenkernel/intern/fcurve_driver.c b/source/blender/blenkernel/intern/fcurve_driver.c
index 10d804f437e..b11a3cb9457 100644
--- a/source/blender/blenkernel/intern/fcurve_driver.c
+++ b/source/blender/blenkernel/intern/fcurve_driver.c
@@ -21,12 +21,6 @@
* \ingroup bke
*/
-// #include <float.h>
-// #include <math.h>
-// #include <stddef.h>
-// #include <stdio.h>
-// #include <string.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
@@ -66,17 +60,19 @@ static ThreadMutex python_driver_lock = BLI_MUTEX_INITIALIZER;
static CLG_LogRef LOG = {"bke.fcurve"};
-/* Driver Variables --------------------------- */
+/* -------------------------------------------------------------------- */
+/** \name Driver Variables
+ * \{ */
/* TypeInfo for Driver Variables (dvti) */
typedef struct DriverVarTypeInfo {
- /* evaluation callback */
+ /* Evaluation callback. */
float (*get_value)(ChannelDriver *driver, DriverVar *dvar);
- /* allocation of target slots */
- int num_targets; /* number of target slots required */
- const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots */
- short target_flags[MAX_DRIVER_TARGETS]; /* flags defining the requirements for each slot */
+ /* Allocation of target slots. */
+ int num_targets; /* Number of target slots required. */
+ const char *target_names[MAX_DRIVER_TARGETS]; /* UI names that should be given to the slots. */
+ short target_flags[MAX_DRIVER_TARGETS]; /* Flags defining the requirements for each slot. */
} DriverVarTypeInfo;
/* Macro to begin definitions */
@@ -85,7 +81,11 @@ typedef struct DriverVarTypeInfo {
/* Macro to end definitions */
#define END_DVAR_TYPEDEF }
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Target Utilities
+ * \{ */
static ID *dtar_id_ensure_proxy_from(ID *id)
{
@@ -107,14 +107,14 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
int index = -1;
float value = 0.0f;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return 0.0f;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -125,12 +125,12 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
return 0.0f;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (!RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -144,9 +144,9 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
if (RNA_property_array_check(prop)) {
- /* array */
+ /* Array. */
if (index < 0 || index >= RNA_property_array_length(&ptr, prop)) {
- /* out of bounds */
+ /* Out of bounds. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: array index is out of bounds for %s -> %s (%d)",
@@ -175,7 +175,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
else {
- /* not an array */
+ /* Not an array. */
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
value = (float)RNA_property_boolean_get(&ptr, prop);
@@ -194,7 +194,7 @@ static float dtar_get_prop_val(ChannelDriver *driver, DriverTarget *dtar)
}
}
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return value;
}
@@ -214,14 +214,14 @@ bool driver_get_variable_property(ChannelDriver *driver,
ID *id;
int index = -1;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dtar)) {
return false;
}
id = dtar_id_ensure_proxy_from(dtar->id);
- /* error check for missing pointer... */
+ /* Error check for missing pointer. */
if (id == NULL) {
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG, "driver has an invalid target to use (path = %s)", dtar->rna_path);
@@ -232,19 +232,19 @@ bool driver_get_variable_property(ChannelDriver *driver,
return false;
}
- /* get RNA-pointer for the ID-block given in target */
+ /* Get RNA-pointer for the ID-block given in target. */
RNA_id_pointer_create(id, &id_ptr);
- /* get property to read from, and get value as appropriate */
+ /* Get property to read from, and get value as appropriate. */
if (dtar->rna_path == NULL || dtar->rna_path[0] == '\0') {
ptr = PointerRNA_NULL;
- prop = NULL; /* ok */
+ prop = NULL; /* OK. */
}
else if (RNA_path_resolve_property_full(&id_ptr, dtar->rna_path, &ptr, &prop, &index)) {
- /* ok */
+ /* OK. */
}
else {
- /* path couldn't be resolved */
+ /* Path couldn't be resolved. */
if (G.debug & G_DEBUG) {
CLOG_ERROR(&LOG,
"Driver Evaluation Error: cannot resolve target for %s -> %s",
@@ -265,7 +265,7 @@ bool driver_get_variable_property(ChannelDriver *driver,
*r_prop = prop;
*r_index = index;
- /* if we're still here, we should be ok... */
+ /* If we're still here, we should be ok. */
dtar->flag &= ~DTAR_FLAG_INVALID;
return true;
}
@@ -277,14 +277,14 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
}
else {
- /* target seems to be OK now... */
+ /* Target seems to be OK now. */
dtar->flag &= ~DTAR_FLAG_INVALID;
valid_targets++;
}
@@ -294,21 +294,25 @@ static short driver_check_valid_targets(ChannelDriver *driver, DriverVar *dvar)
return valid_targets;
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Utilities
+ * \{ */
-/* evaluate 'single prop' driver variable */
+/* Evaluate 'single prop' driver variable. */
static float dvar_eval_singleProp(ChannelDriver *driver, DriverVar *dvar)
{
- /* just evaluate the first target slot */
+ /* Just evaluate the first target slot. */
return dtar_get_prop_val(driver, &dvar->targets[0]);
}
-/* evaluate 'rotation difference' driver variable */
+/* Evaluate 'rotation difference' driver variable. */
static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
{
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (driver_check_valid_targets(driver, dvar) != 2) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -324,31 +328,31 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
/* NOTE: for now, these are all just worldspace */
for (int i = 0; i < 2; i++) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
DriverTarget *dtar = &dvar->targets[i];
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
mat[i] = pchan->pose_mat;
}
else {
- /* object */
+ /* Object. */
mat[i] = ob->obmat;
}
}
float q1[4], q2[4], quat[4], angle;
- /* use the final posed locations */
+ /* Use the final posed locations. */
mat4_to_quat(q1, mat[0]);
mat4_to_quat(q2, mat[1]);
@@ -360,15 +364,18 @@ static float dvar_eval_rotDiff(ChannelDriver *driver, DriverVar *dvar)
return (angle > (float)M_PI) ? (float)((2.0f * (float)M_PI) - angle) : (float)(angle);
}
-/* evaluate 'location difference' driver variable */
-/* TODO: this needs to take into account space conversions... */
+/**
+ * Evaluate 'location difference' driver variable.
+ *
+ * TODO: this needs to take into account space conversions.
+ */
static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
{
float loc1[3] = {0.0f, 0.0f, 0.0f};
float loc2[3] = {0.0f, 0.0f, 0.0f};
short valid_targets = driver_check_valid_targets(driver, dvar);
- /* make sure we have enough valid targets to use - all or nothing for now... */
+ /* Make sure we have enough valid targets to use - all or nothing for now. */
if (valid_targets < dvar->num_targets) {
if (G.debug & G_DEBUG) {
CLOG_WARN(&LOG,
@@ -381,72 +388,72 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
/* SECOND PASS: get two location values */
- /* NOTE: for now, these are all just worldspace */
+ /* NOTE: for now, these are all just world-space */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
- /* get pointer to loc values to store in */
+ /* Get pointer to loc values to store in. */
Object *ob = (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float tmp_loc[3];
- /* after the checks above, the targets should be valid here... */
+ /* After the checks above, the targets should be valid here. */
BLI_assert((ob != NULL) && (GS(ob->id.name) == ID_OB));
- /* try to get posechannel */
+ /* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
- /* check if object or bone */
+ /* Check if object or bone. */
if (pchan) {
- /* bone */
+ /* Bone. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, pchan->loc);
}
}
else {
- /* convert to worldspace */
+ /* Convert to worldspace. */
copy_v3_v3(tmp_loc, pchan->pose_head);
mul_m4_v3(ob->obmat, tmp_loc);
}
}
else {
- /* object */
+ /* Object. */
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* XXX: this should practically be the same as transform space... */
+ /* XXX: this should practically be the same as transform space. */
float mat[4][4];
- /* extract transform just like how the constraints do it! */
+ /* Extract transform just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
- /* ... and from that, we get our transform */
+ /* ... and from that, we get our transform. */
copy_v3_v3(tmp_loc, mat[3]);
}
else {
- /* transform space (use transform values directly) */
+ /* Transform space (use transform values directly). */
copy_v3_v3(tmp_loc, ob->loc);
}
}
else {
- /* worldspace */
+ /* World-space. */
copy_v3_v3(tmp_loc, ob->obmat[3]);
}
}
- /* copy the location to the right place */
+ /* Copy the location to the right place. */
if (tarIndex) {
copy_v3_v3(loc2, tmp_loc);
}
@@ -456,13 +463,14 @@ static float dvar_eval_locDiff(ChannelDriver *driver, DriverVar *dvar)
}
DRIVER_TARGETS_LOOPER_END;
- /* if we're still here, there should now be two targets to use,
- * so just take the length of the vector between these points
- */
+ /* If we're still here, there should now be two targets to use,
+ * so just take the length of the vector between these points. */
return len_v3v3(loc1, loc2);
}
-/* evaluate 'transform channel' driver variable */
+/**
+ * Evaluate 'transform channel' driver variable.
+ */
static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
{
DriverTarget *dtar = &dvar->targets[0];
@@ -473,17 +481,16 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
bool use_eulers = false;
short rot_order = ROT_MODE_EUL;
- /* check if this target has valid data */
+ /* Check if this target has valid data. */
if ((ob == NULL) || (GS(ob->id.name) != ID_OB)) {
- /* invalid target, so will not have enough targets */
+ /* Invalid target, so will not have enough targets. */
driver->flag |= DRIVER_FLAG_INVALID;
dtar->flag |= DTAR_FLAG_INVALID;
return 0.0f;
}
- else {
- /* target should be valid now */
- dtar->flag &= ~DTAR_FLAG_INVALID;
- }
+
+ /* Target should be valid now. */
+ dtar->flag &= ~DTAR_FLAG_INVALID;
/* Try to get pose-channel. */
pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
@@ -495,7 +502,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
* but #DTAR_FLAG_LOCAL_CONSTS is for all the common "corrective-shapes-for-limbs" situations.
*/
if (pchan) {
- /* bone */
+ /* Bone. */
if (pchan->rotmode > 0) {
copy_v3_v3(oldEul, pchan->eul);
rot_order = pchan->rotmode;
@@ -504,16 +511,15 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, pchan->pose_mat);
BKE_constraint_mat_convertspace(
ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* specially calculate local matrix, since chan_mat is not valid
+ /* Specially calculate local matrix, since chan_mat is not valid
* since it stores delta transform of pose_mat so that deforms work
- * so it cannot be used here for "transform" space
- */
+ * so it cannot be used here for "transform" space. */
BKE_pchan_to_mat4(pchan, mat);
}
}
@@ -523,7 +529,7 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
}
}
else {
- /* object */
+ /* Object. */
if (ob->rotmode > 0) {
copy_v3_v3(oldEul, ob->rot);
rot_order = ob->rotmode;
@@ -532,42 +538,39 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
- /* just like how the constraints do it! */
+ /* Just like how the constraints do it! */
copy_m4_m4(mat, ob->obmat);
BKE_constraint_mat_convertspace(
ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, false);
}
else {
- /* transforms to matrix */
+ /* Transforms to matrix. */
BKE_object_to_mat4(ob, mat);
}
}
else {
- /* worldspace matrix - just the good-old one */
+ /* World-space matrix - just the good-old one. */
copy_m4_m4(mat, ob->obmat);
}
}
- /* check which transform */
+ /* Check which transform. */
if (dtar->transChan >= MAX_DTAR_TRANSCHAN_TYPES) {
- /* not valid channel */
+ /* Not valid channel. */
return 0.0f;
}
- else if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
+ if (dtar->transChan == DTAR_TRANSCHAN_SCALE_AVG) {
/* Cubic root of the change in volume, equal to the geometric mean
* of scale over all three axes unless the matrix includes shear. */
return cbrtf(mat4_to_volume_scale(mat));
}
- else if (ELEM(dtar->transChan,
- DTAR_TRANSCHAN_SCALEX,
- DTAR_TRANSCHAN_SCALEY,
- DTAR_TRANSCHAN_SCALEZ)) {
+ if (ELEM(dtar->transChan, DTAR_TRANSCHAN_SCALEX, DTAR_TRANSCHAN_SCALEY, DTAR_TRANSCHAN_SCALEZ)) {
/* Extract scale, and choose the right axis,
* inline 'mat4_to_size'. */
return len_v3(mat[dtar->transChan - DTAR_TRANSCHAN_SCALEX]);
}
- else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
- /* extract rotation as eulers (if needed)
+ if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
+ /* Extract rotation as eulers (if needed)
* - definitely if rotation order isn't eulers already
* - if eulers, then we have 2 options:
* a) decompose transform matrix as required, then try to make eulers from
@@ -595,10 +598,9 @@ static float dvar_eval_transChan(ChannelDriver *driver, DriverVar *dvar)
return quat[channel];
}
- else {
- /* extract location and choose right axis */
- return mat[3][dtar->transChan];
- }
+
+ /* Extract location and choose right axis. */
+ return mat[3][dtar->transChan];
}
/* Convert a quaternion to pseudo-angles representing the weighted amount of rotation. */
@@ -666,83 +668,90 @@ void BKE_driver_target_matrix_to_rot_channels(
}
}
-/* ......... */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Variable Type Info
+ * \{ */
/* Table of Driver Variable Type Info Data */
static DriverVarTypeInfo dvar_types[MAX_DVAR_TYPES] = {
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_SINGLE_PROP) dvar_eval_singleProp, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Property"}, /* UI names for targets */
- {0} /* flags */
+ {0} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_ROT_DIFF) dvar_eval_rotDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* eval callback */
- 2, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_LOC_DIFF) dvar_eval_locDiff, /* Eval callback. */
+ 2, /* Number of targets used. */
{"Object/Bone 1", "Object/Bone 2"}, /* UI names for targets */
{DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY,
- DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
- BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* eval callback */
- 1, /* number of targets used */
+ BEGIN_DVAR_TYPEDEF(DVAR_TYPE_TRANSFORM_CHAN) dvar_eval_transChan, /* Eval callback. */
+ 1, /* Number of targets used. */
{"Object/Bone"}, /* UI names for targets */
- {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* flags */
+ {DTAR_FLAG_STRUCT_REF | DTAR_FLAG_ID_OB_ONLY} /* Flags. */
END_DVAR_TYPEDEF,
};
/* Get driver variable typeinfo */
static const DriverVarTypeInfo *get_dvar_typeinfo(int type)
{
- /* check if valid type */
+ /* Check if valid type. */
if ((type >= 0) && (type < MAX_DVAR_TYPES)) {
return &dvar_types[type];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
-/* Driver API --------------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver API
+ * \{ */
/* Perform actual freeing driver variable and remove it from the given list */
void driver_free_variable(ListBase *variables, DriverVar *dvar)
{
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* free target vars
+ /* Free target vars:
* - need to go over all of them, not just up to the ones that are used
* currently, since there may be some lingering RNA paths from
* previous users needing freeing
*/
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* free RNA path if applicable */
+ /* Free RNA path if applicable. */
if (dtar->rna_path) {
MEM_freeN(dtar->rna_path);
}
}
DRIVER_TARGETS_LOOPER_END;
- /* remove the variable from the driver */
+ /* Remove the variable from the driver. */
BLI_freelinkN(variables, dvar);
}
/* Free the driver variable and do extra updates */
void driver_free_variable_ex(ChannelDriver *driver, DriverVar *dvar)
{
- /* remove and free the driver variable */
+ /* Remove and free the driver variable. */
driver_free_variable(&driver->variables, dvar);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
}
@@ -753,9 +762,9 @@ void driver_variables_copy(ListBase *dst_vars, const ListBase *src_vars)
BLI_duplicatelist(dst_vars, src_vars);
LISTBASE_FOREACH (DriverVar *, dvar, dst_vars) {
- /* need to go over all targets so that we don't leave any dangling paths */
+ /* Need to go over all targets so that we don't leave any dangling paths. */
DRIVER_TARGETS_LOOPER_BEGIN (dvar) {
- /* make a copy of target's rna path if available */
+ /* Make a copy of target's rna path if available. */
if (dtar->rna_path) {
dtar->rna_path = MEM_dupallocN(dtar->rna_path);
}
@@ -769,25 +778,24 @@ void driver_change_variable_type(DriverVar *dvar, int type)
{
const DriverVarTypeInfo *dvti = get_dvar_typeinfo(type);
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, dvar, dvti)) {
return;
}
- /* set the new settings */
+ /* Set the new settings. */
dvar->type = type;
dvar->num_targets = dvti->num_targets;
- /* make changes to the targets based on the defines for these types
- * NOTE: only need to make sure the ones we're using here are valid...
- */
+ /* Make changes to the targets based on the defines for these types.
+ * NOTE: only need to make sure the ones we're using here are valid. */
DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
short flags = dvti->target_flags[tarIndex];
- /* store the flags */
+ /* Store the flags. */
dtar->flag = flags;
- /* object ID types only, or idtype not yet initialized */
+ /* Object ID types only, or idtype not yet initialized. */
if ((flags & DTAR_FLAG_ID_OB_ONLY) || (dtar->idtype == 0)) {
dtar->idtype = ID_OB;
}
@@ -804,12 +812,12 @@ void driver_variable_name_validate(DriverVar *dvar)
'?', ':', ';', '<', '>', '{', '}', '[', ']', '|', ' ', '.', '\t', '\n', '\r',
};
- /* sanity checks */
+ /* Sanity checks. */
if (dvar == NULL) {
return;
}
- /* clear all invalid-name flags */
+ /* Clear all invalid-name flags. */
dvar->flag &= ~DVAR_ALL_INVALID_FLAGS;
/* 0) Zero-length identifiers are not allowed */
@@ -870,16 +878,16 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
{
DriverVar *dvar;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* make a new variable */
+ /* Make a new variable. */
dvar = MEM_callocN(sizeof(DriverVar), "DriverVar");
BLI_addtail(&driver->variables, dvar);
- /* give the variable a 'unique' name */
+ /* Give the variable a 'unique' name. */
strcpy(dvar->name, CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "var"));
BLI_uniquename(&driver->variables,
dvar,
@@ -888,13 +896,13 @@ DriverVar *driver_add_new_variable(ChannelDriver *driver)
offsetof(DriverVar, name),
sizeof(dvar->name));
- /* set the default type to 'single prop' */
+ /* Set the default type to 'single prop'. */
driver_change_variable_type(dvar, DVAR_TYPE_SINGLE_PROP);
- /* since driver variables are cached, the expression needs re-compiling too */
+ /* Since driver variables are cached, the expression needs re-compiling too. */
BKE_driver_invalidate_expression(driver, false, true);
- /* return the target */
+ /* Return the target. */
return dvar;
}
@@ -904,20 +912,20 @@ void fcurve_free_driver(FCurve *fcu)
ChannelDriver *driver;
DriverVar *dvar, *dvarn;
- /* sanity checks */
+ /* Sanity checks. */
if (ELEM(NULL, fcu, fcu->driver)) {
return;
}
driver = fcu->driver;
- /* free driver targets */
+ /* Free driver targets. */
for (dvar = driver->variables.first; dvar; dvar = dvarn) {
dvarn = dvar->next;
driver_free_variable_ex(driver, dvar);
}
#ifdef WITH_PYTHON
- /* free compiled driver expression */
+ /* Free compiled driver expression. */
if (driver->expr_comp) {
BPY_DECREF(driver->expr_comp);
}
@@ -936,27 +944,31 @@ ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver)
{
ChannelDriver *ndriver;
- /* sanity checks */
+ /* Sanity checks. */
if (driver == NULL) {
return NULL;
}
- /* copy all data */
+ /* Copy all data. */
ndriver = MEM_dupallocN(driver);
ndriver->expr_comp = NULL;
ndriver->expr_simple = NULL;
- /* copy variables */
+ /* Copy variables. */
- /* to get rid of refs to non-copied data (that's still used on original) */
+ /* To get rid of refs to non-copied data (that's still used on original). */
BLI_listbase_clear(&ndriver->variables);
driver_variables_copy(&ndriver->variables, &driver->variables);
- /* return the new driver */
+ /* Return the new driver. */
return ndriver;
}
-/* Driver Expression Evaluation --------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Expression Evaluation
+ * \{ */
/* Index constants for the expression parameter array. */
enum {
@@ -1026,7 +1038,7 @@ static bool driver_evaluate_simple_expr(ChannelDriver *driver,
return true;
default:
- /* arriving here means a bug, not user error */
+ /* Arriving here means a bug, not user error. */
CLOG_ERROR(&LOG, "simple driver expression evaluation failed: '%s'", driver->expression);
return false;
}
@@ -1108,10 +1120,9 @@ bool BKE_driver_expression_depends_on_time(ChannelDriver *driver)
/* Simple expressions can be checked exactly. */
return driver_check_simple_expr_depends_on_time(driver->expr_simple);
}
- else {
- /* Otherwise, heuristically scan the expression string for certain patterns. */
- return python_driver_exression_depends_on_time(driver->expression);
- }
+
+ /* Otherwise, heuristically scan the expression string for certain patterns. */
+ return python_driver_exression_depends_on_time(driver->expression);
}
/* Reset cached compiled expression data */
@@ -1135,22 +1146,25 @@ void BKE_driver_invalidate_expression(ChannelDriver *driver,
#endif
}
-/* Driver Evaluation -------------------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Driver Evaluation
+ * \{ */
/* Evaluate a Driver Variable to get a value that contributes to the final */
float driver_get_variable_value(ChannelDriver *driver, DriverVar *dvar)
{
const DriverVarTypeInfo *dvti;
- /* sanity check */
+ /* Sanity check. */
if (ELEM(NULL, driver, dvar)) {
return 0.0f;
}
- /* call the relevant callbacks to get the variable value
+ /* Call the relevant callbacks to get the variable value
* using the variable type info, storing the obtained value
- * in dvar->curval so that drivers can be debugged
- */
+ * in `dvar->curval` so that drivers can be debugged. */
dvti = get_dvar_typeinfo(dvar->type);
if (dvti && dvti->get_value) {
@@ -1167,25 +1181,25 @@ static void evaluate_driver_sum(ChannelDriver *driver)
{
DriverVar *dvar;
- /* check how many variables there are first (i.e. just one?) */
+ /* Check how many variables there are first (i.e. just one?). */
if (BLI_listbase_is_single(&driver->variables)) {
- /* just one target, so just use that */
+ /* Just one target, so just use that. */
dvar = driver->variables.first;
driver->curval = driver_get_variable_value(driver, dvar);
return;
}
- /* more than one target, so average the values of the targets */
+ /* More than one target, so average the values of the targets. */
float value = 0.0f;
int tot = 0;
- /* loop through targets, adding (hopefully we don't get any overflow!) */
+ /* Loop through targets, adding (hopefully we don't get any overflow!). */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
value += driver_get_variable_value(driver, dvar);
tot++;
}
- /* perform operations on the total if appropriate */
+ /* Perform operations on the total if appropriate. */
if (driver->type == DRIVER_TYPE_AVERAGE) {
driver->curval = tot ? (value / (float)tot) : 0.0f;
}
@@ -1199,34 +1213,34 @@ static void evaluate_driver_min_max(ChannelDriver *driver)
DriverVar *dvar;
float value = 0.0f;
- /* loop through the variables, getting the values and comparing them to existing ones */
+ /* Loop through the variables, getting the values and comparing them to existing ones. */
for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* get value */
+ /* Get value. */
float tmp_val = driver_get_variable_value(driver, dvar);
- /* store this value if appropriate */
+ /* Store this value if appropriate. */
if (dvar->prev) {
- /* check if greater/smaller than the baseline */
+ /* Check if greater/smaller than the baseline. */
if (driver->type == DRIVER_TYPE_MAX) {
- /* max? */
+ /* Max? */
if (tmp_val > value) {
value = tmp_val;
}
}
else {
- /* min? */
+ /* Min? */
if (tmp_val < value) {
value = tmp_val;
}
}
}
else {
- /* first item - make this the baseline for comparisons */
+ /* First item - make this the baseline for comparisons. */
value = tmp_val;
}
}
- /* store value in driver */
+ /* Store value in driver. */
driver->curval = value;
}
@@ -1235,62 +1249,63 @@ static void evaluate_driver_python(PathResolvedRNA *anim_rna,
ChannelDriver *driver_orig,
const AnimationEvalContext *anim_eval_context)
{
- /* check for empty or invalid expression */
+ /* Check for empty or invalid expression. */
if ((driver_orig->expression[0] == '\0') || (driver_orig->flag & DRIVER_FLAG_INVALID)) {
driver->curval = 0.0f;
}
else if (!driver_try_evaluate_simple_expr(
driver, driver_orig, &driver->curval, anim_eval_context->eval_time)) {
#ifdef WITH_PYTHON
- /* this evaluates the expression using Python, and returns its result:
- * - on errors it reports, then returns 0.0f
- */
+ /* This evaluates the expression using Python, and returns its result:
+ * - on errors it reports, then returns 0.0f. */
BLI_mutex_lock(&python_driver_lock);
driver->curval = BPY_driver_exec(anim_rna, driver, driver_orig, anim_eval_context);
BLI_mutex_unlock(&python_driver_lock);
-#else /* WITH_PYTHON*/
+#else /* WITH_PYTHON */
UNUSED_VARS(anim_rna, anim_eval_context);
-#endif /* WITH_PYTHON*/
+#endif /* WITH_PYTHON */
}
}
-/* Evaluate an Channel-Driver to get a 'time' value to use instead of "evaltime"
- * - "evaltime" is the frame at which F-Curve is being evaluated
- * - has to return a float value
- * - driver_orig is where we cache Python expressions, in case of COW
+/**
+ * Evaluate an Channel-Driver to get a 'time' value to use
+ * instead of `anim_eval_context->eval_time`.
+ *
+ * - `anim_eval_context->eval_time` is the frame at which F-Curve is being evaluated.
+ * - Has to return a float value.
+ * - \a driver_orig is where we cache Python expressions, in case of COW
*/
float evaluate_driver(PathResolvedRNA *anim_rna,
ChannelDriver *driver,
ChannelDriver *driver_orig,
const AnimationEvalContext *anim_eval_context)
{
- /* check if driver can be evaluated */
+ /* Check if driver can be evaluated. */
if (driver_orig->flag & DRIVER_FLAG_INVALID) {
return 0.0f;
}
switch (driver->type) {
- case DRIVER_TYPE_AVERAGE: /* average values of driver targets */
- case DRIVER_TYPE_SUM: /* sum values of driver targets */
+ case DRIVER_TYPE_AVERAGE: /* Average values of driver targets. */
+ case DRIVER_TYPE_SUM: /* Sum values of driver targets. */
evaluate_driver_sum(driver);
break;
- case DRIVER_TYPE_MIN: /* smallest value */
- case DRIVER_TYPE_MAX: /* largest value */
+ case DRIVER_TYPE_MIN: /* Smallest value. */
+ case DRIVER_TYPE_MAX: /* Largest value. */
evaluate_driver_min_max(driver);
break;
- case DRIVER_TYPE_PYTHON: /* expression */
+ case DRIVER_TYPE_PYTHON: /* Expression. */
evaluate_driver_python(anim_rna, driver, driver_orig, anim_eval_context);
break;
default:
- /* special 'hack' - just use stored value
+ /* Special 'hack' - just use stored value
* This is currently used as the mechanism which allows animated settings to be able
- * to be changed via the UI.
- */
+ * to be changed via the UI. */
break;
}
- /* return value for driver */
+ /* Return value for driver. */
return driver->curval;
}
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 079b436a3ea..b37d940195e 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -533,14 +533,14 @@ static bool BKE_fluid_modifier_init(
/* Allocate fluid. */
return BKE_fluid_reallocate_fluid(fds, fds->res, 0);
}
- else if (fmd->type & MOD_FLUID_TYPE_FLOW) {
+ if (fmd->type & MOD_FLUID_TYPE_FLOW) {
if (!fmd->flow) {
BKE_fluid_modifier_create_type_data(fmd);
}
fmd->time = scene_framenr;
return true;
}
- else if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
+ if (fmd->type & MOD_FLUID_TYPE_EFFEC) {
if (!fmd->effector) {
BKE_fluid_modifier_create_type_data(fmd);
}
@@ -575,7 +575,7 @@ static int get_light(ViewLayer *view_layer, float *light)
copy_v3_v3(light, base_tmp->object->obmat[3]);
return 1;
}
- else if (!found_light) {
+ if (!found_light) {
copy_v3_v3(light, base_tmp->object->obmat[3]);
found_light = 1;
}
@@ -655,7 +655,7 @@ typedef struct FluidObjectBB {
int total_cells, valid;
} FluidObjectBB;
-static void bb_boundInsert(FluidObjectBB *bb, float point[3])
+static void bb_boundInsert(FluidObjectBB *bb, const float point[3])
{
int i = 0;
if (!bb->valid) {
@@ -955,7 +955,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata,
for (int y = data->min[1]; y < data->max[1]; y++) {
const int index = manta_get_index(
x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]);
- float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f};
+ const float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f};
/* Calculate object velocities. Result in bb->velocity. */
sample_effector(data->fes,
@@ -1119,6 +1119,7 @@ static void ensure_obstaclefields(FluidDomainSettings *fds)
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE) {
manta_ensure_guiding(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_obstacleflags(FluidDomainSettings *fds,
@@ -2596,7 +2597,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
manta_smoke_ensure_fire(fds->fluid, fds->fmd);
}
if (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) {
- /* initialize all smoke with "active_color" */
+ /* Initialize all smoke with "active_color". */
manta_smoke_ensure_colors(fds->fluid, fds->fmd);
}
if (fds->type == FLUID_DOMAIN_TYPE_LIQUID &&
@@ -2605,6 +2606,7 @@ static void ensure_flowsfields(FluidDomainSettings *fds)
fds->particle_type & FLUID_DOMAIN_PARTICLE_TRACER)) {
manta_liquid_ensure_sndparts(fds->fluid, fds->fmd);
}
+ manta_update_pointers(fds->fluid, fds->fmd, false);
}
static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int numflowobj)
@@ -2617,7 +2619,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
FLUID_DOMAIN_ACTIVE_HEAT | FLUID_DOMAIN_ACTIVE_FIRE);
active_fields &= ~prev_flags;
- /* Monitor active fields based on flow settings */
+ /* Monitor active fields based on flow settings. */
for (flow_index = 0; flow_index < numflowobj; flow_index++) {
Object *flow_ob = flowobjs[flow_index];
FluidModifierData *fmd2 = (FluidModifierData *)BKE_modifiers_findby_type(flow_ob,
@@ -2628,6 +2630,7 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
+ /* Activate specific grids if at least one flow object requires this grid. */
if ((fmd2->type & MOD_FLUID_TYPE_FLOW) && fmd2->flow) {
FluidFlowSettings *ffs = fmd2->flow;
if (!ffs) {
@@ -2648,17 +2651,17 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
continue;
}
- /* activate heat field if flow produces any heat */
- if (ffs->temperature) {
+ /* Activate heat field if a flow object produces any heat. */
+ if (ffs->temperature != 0.0) {
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
}
- /* activate fuel field if flow adds any fuel */
- if (ffs->fuel_amount &&
- (ffs->type == FLUID_FLOW_TYPE_FIRE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
+ /* Activate fuel field if a flow object is of fire type. */
+ if (ffs->fuel_amount != 0.0 || ffs->type == FLUID_FLOW_TYPE_FIRE ||
+ ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE) {
active_fields |= FLUID_DOMAIN_ACTIVE_FIRE;
}
- /* activate color field if flows add smoke with varying colors */
- if (ffs->density &&
+ /* Activate color field if flows add smoke with varying colors. */
+ if (ffs->density != 0.0 &&
(ffs->type == FLUID_FLOW_TYPE_SMOKE || ffs->type == FLUID_FLOW_TYPE_SMOKEFIRE)) {
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, ffs->color);
@@ -2671,11 +2674,11 @@ static void update_flowsflags(FluidDomainSettings *fds, Object **flowobjs, int n
}
}
}
- /* Monitor active fields based on domain settings */
+ /* Monitor active fields based on domain settings. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && active_fields & FLUID_DOMAIN_ACTIVE_FIRE) {
- /* heat is always needed for fire */
+ /* Heat is always needed for fire. */
active_fields |= FLUID_DOMAIN_ACTIVE_HEAT;
- /* also activate colors if domain smoke color differs from active color */
+ /* Also activate colors if domain smoke color differs from active color. */
if (!(active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET)) {
copy_v3_v3(fds->active_color, fds->flame_smoke_color);
active_fields |= FLUID_DOMAIN_ACTIVE_COLOR_SET;
@@ -2924,8 +2927,21 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
float *velx_initial = manta_get_in_velocity_x(fds->fluid);
float *vely_initial = manta_get_in_velocity_y(fds->fluid);
float *velz_initial = manta_get_in_velocity_z(fds->fluid);
- uint z;
+ float *forcex = manta_get_force_x(fds->fluid);
+ float *forcey = manta_get_force_y(fds->fluid);
+ float *forcez = manta_get_force_z(fds->fluid);
+
+ BLI_assert(forcex && forcey && forcez);
+
+ /* Either all or no components have to exist. */
+ BLI_assert((color_r && color_g && color_b) || (!color_r && !color_g && !color_b));
+ BLI_assert((color_r_in && color_g_in && color_b_in) ||
+ (!color_r_in && !color_g_in && !color_b_in));
+ BLI_assert((velx_initial && vely_initial && velz_initial) ||
+ (!velx_initial && !vely_initial && !velz_initial));
+
+ uint z;
/* Grid reset before writing again. */
for (z = 0; z < fds->res[0] * fds->res[1] * fds->res[2]; z++) {
/* Only reset static phi on first frame, dynamic phi gets reset every time. */
@@ -2949,7 +2965,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (heat_in) {
heat_in[z] = heat[z];
}
- if (color_r_in) {
+ if (color_r_in && color_g_in && color_b_in) {
color_r_in[z] = color_r[z];
color_g_in[z] = color_b[z];
color_b_in[z] = color_g[z];
@@ -2961,11 +2977,15 @@ static void update_flowsfluids(struct Depsgraph *depsgraph,
if (emission_in) {
emission_in[z] = 0.0f;
}
- if (velx_initial) {
+ if (velx_initial && vely_initial && velz_initial) {
velx_initial[z] = 0.0f;
vely_initial[z] = 0.0f;
velz_initial[z] = 0.0f;
}
+ /* Reset forces here as update_effectors() is skipped when no external forces are present. */
+ forcex[z] = 0.0f;
+ forcey[z] = 0.0f;
+ forcez[z] = 0.0f;
}
/* Apply emission data for every flow object. */
@@ -3149,13 +3169,13 @@ static void update_effectors_task_cb(void *__restrict userdata,
continue;
}
- /* get velocities from manta grid space and convert to blender units */
+ /* Get velocities from manta grid space and convert to blender units. */
vel[0] = data->velocity_x[index];
vel[1] = data->velocity_y[index];
vel[2] = data->velocity_z[index];
mul_v3_fl(vel, fds->dx);
- /* convert vel to global space */
+ /* Convert vel to global space. */
mag = len_v3(vel);
mul_mat3_m4_v3(fds->obmat, vel);
normalize_v3(vel);
@@ -3166,18 +3186,18 @@ static void update_effectors_task_cb(void *__restrict userdata,
voxel_center[2] = fds->p0[2] + fds->cell_size[2] * ((float)(z + fds->res_min[2]) + 0.5f);
mul_m4_v3(fds->obmat, voxel_center);
- /* do effectors */
+ /* Do effectors. */
pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint);
BKE_effectors_apply(
data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL);
- /* convert retvel to local space */
+ /* Convert retvel to local space. */
mag = len_v3(retvel);
mul_mat3_m4_v3(fds->imat, retvel);
normalize_v3(retvel);
mul_v3_fl(retvel, mag);
- /* constrain forces to interval -1 to 1 */
+ /* Constrain forces to interval -1 to 1. */
data->force_x[index] = min_ff(max_ff(-1.0f, retvel[0] * 0.2f), 1.0f);
data->force_y[index] = min_ff(max_ff(-1.0f, retvel[1] * 0.2f), 1.0f);
data->force_z[index] = min_ff(max_ff(-1.0f, retvel[2] * 0.2f), 1.0f);
@@ -3617,14 +3637,16 @@ static int manta_step(
fds->time_per_frame = time_per_frame;
fds->time_total = time_total;
}
+
/* Total time must not exceed framecount times framelength. Correct tiny errors here. */
CLAMP(fds->time_total, fds->time_total, time_total_old + fds->frame_length);
+ /* Compute shadow grid for gas simulations. Make sure to skip if bake job was canceled early. */
if (fds->type == FLUID_DOMAIN_TYPE_GAS && result) {
manta_smoke_calc_transparency(fds, DEG_get_evaluated_view_layer(depsgraph));
}
- BLI_mutex_unlock(&object_update_lock);
+ BLI_mutex_unlock(&object_update_lock);
return result;
}
@@ -3716,29 +3738,35 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
int mode = fds->cache_type;
/* Do not process modifier if current frame is out of cache range. */
+ bool escape = false;
switch (mode) {
case FLUID_DOMAIN_CACHE_ALL:
case FLUID_DOMAIN_CACHE_MODULAR:
if (fds->cache_frame_offset > 0) {
if (scene_framenr < fds->cache_frame_start ||
scene_framenr > fds->cache_frame_end + fds->cache_frame_offset) {
- return;
+ escape = true;
}
}
else {
if (scene_framenr < fds->cache_frame_start + fds->cache_frame_offset ||
scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
}
break;
case FLUID_DOMAIN_CACHE_REPLAY:
default:
if (scene_framenr < fds->cache_frame_start || scene_framenr > fds->cache_frame_end) {
- return;
+ escape = true;
}
break;
}
+ /* If modifier will not be processed, update/flush pointers from (old) fluid object once more. */
+ if (escape && fds->fluid) {
+ manta_update_pointers(fds->fluid, fmd, true);
+ return;
+ }
/* Reset fluid if no fluid present. Also resets active fields. */
if (!fds->fluid) {
@@ -3830,7 +3858,15 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
has_mesh = manta_has_mesh(fds->fluid, fmd, scene_framenr);
has_particles = manta_has_particles(fds->fluid, fmd, scene_framenr);
has_guide = manta_has_guiding(fds->fluid, fmd, scene_framenr, guide_parent);
- has_config = false;
+ has_config = manta_read_config(fds->fluid, fmd, scene_framenr);
+
+ /* When reading data from cache (has_config == true) ensure that active fields are allocated.
+ * update_flowsflags() and update_obstacleflags() will not find flow sources hidden from renders.
+ * See also: T72192. */
+ if (has_config) {
+ ensure_flowsfields(fds);
+ ensure_obstaclefields(fds);
+ }
bool baking_data, baking_noise, baking_mesh, baking_particles, baking_guide;
baking_data = fds->cache_flag & FLUID_DOMAIN_BAKING_DATA;
@@ -3947,7 +3983,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read mesh cache. */
if (with_liquid && with_mesh) {
- has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ if (mesh_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, mesh_frame);
+ }
/* Update mesh data from file is faster than via Python (manta_read_mesh()). */
has_mesh = manta_read_mesh(fds->fluid, fmd, mesh_frame);
@@ -3955,7 +3993,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read particles cache. */
if (with_liquid && with_particles) {
- has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ if (particles_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, particles_frame);
+ }
read_partial = !baking_data && !baking_particles && next_particles;
read_all = !read_partial && with_resumable_cache;
@@ -3970,7 +4010,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
/* Read noise and data cache */
if (with_smoke && with_noise) {
- has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ if (noise_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, noise_frame);
+ }
/* Only reallocate when just reading cache or when resuming during bake. */
if (has_data && has_config && manta_needs_realloc(fds->fluid, fmd)) {
@@ -3988,7 +4030,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
}
/* Read data cache only */
else {
- has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ if (data_frame != scene_framenr) {
+ has_config = manta_read_config(fds->fluid, fmd, data_frame);
+ }
if (with_smoke) {
/* Read config and realloc fluid object if needed. */
@@ -4073,6 +4117,9 @@ static void BKE_fluid_modifier_processDomain(FluidModifierData *fmd,
}
}
+ /* Ensure that fluid pointers are always up to date at the end of modifier processing. */
+ manta_update_pointers(fds->fluid, fmd, false);
+
fds->flags &= ~FLUID_DOMAIN_FILE_LOAD;
fmd->time = scene_framenr;
}
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index c85283e3653..c973b681fe7 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -285,9 +285,8 @@ static double sinc(double x)
if (fabs(x) < 0.0001) {
return 1.0;
}
- else {
- return sin(M_PI * x) / (M_PI * x);
- }
+
+ return sin(M_PI * x) / (M_PI * x);
}
static void fcm_fn_generator_evaluate(
@@ -525,29 +524,28 @@ int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[],
CLOG_WARN(&LOG, "encountered invalid array");
return 0;
}
- else {
- /* check whether to add before/after/on */
- float framenum;
- /* 'First' Point (when only one point, this case is used) */
- framenum = array[0].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *r_exists = true;
- return 0;
- }
- else if (frame < framenum) {
- return 0;
- }
+ /* check whether to add before/after/on */
+ float framenum;
- /* 'Last' Point */
- framenum = array[(arraylen - 1)].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *r_exists = true;
- return (arraylen - 1);
- }
- else if (frame > framenum) {
- return arraylen;
- }
+ /* 'First' Point (when only one point, this case is used) */
+ framenum = array[0].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *r_exists = true;
+ return 0;
+ }
+ if (frame < framenum) {
+ return 0;
+ }
+
+ /* 'Last' Point */
+ framenum = array[(arraylen - 1)].time;
+ if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
+ *r_exists = true;
+ return (arraylen - 1);
+ }
+ if (frame > framenum) {
+ return arraylen;
}
/* most of the time, this loop is just to find where to put it
@@ -1076,9 +1074,8 @@ const FModifierTypeInfo *get_fmodifier_typeinfo(const int type)
/* there shouldn't be any segfaults here... */
return fmodifiersTypeInfo[type];
}
- else {
- CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type);
- }
+
+ CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type);
return NULL;
}
@@ -1092,9 +1089,8 @@ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm)
if (fcm) {
return get_fmodifier_typeinfo(fcm->type);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* API --------------------------- */
@@ -1239,12 +1235,11 @@ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm)
return true;
}
- else {
- /* XXX this case can probably be removed some day, as it shouldn't happen... */
- CLOG_STR_ERROR(&LOG, "no modifier stack given");
- MEM_freeN(fcm);
- return false;
- }
+
+ /* XXX this case can probably be removed some day, as it shouldn't happen... */
+ CLOG_STR_ERROR(&LOG, "no modifier stack given");
+ MEM_freeN(fcm);
+ return false;
}
/* Remove all of a given F-Curve's modifiers */
@@ -1397,13 +1392,13 @@ static float eval_fmodifier_influence(FModifier *fcm, float evaltime)
/* out of range */
return 0.0f;
}
- else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
+ if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
/* blend in range */
float a = fcm->sfra;
float b = fcm->sfra + fcm->blendin;
return influence * (evaltime - a) / (b - a);
}
- else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
+ if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
/* blend out range */
float a = fcm->efra;
float b = fcm->efra - fcm->blendout;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index dfa5ff6975f..4bedba8f76b 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -193,13 +193,12 @@ static PackedFile *get_builtin_packedfile(void)
return NULL;
}
- else {
- void *mem = MEM_mallocN(builtin_font_size, "vfd_builtin");
- memcpy(mem, builtin_font_data, builtin_font_size);
+ void *mem = MEM_mallocN(builtin_font_size, "vfd_builtin");
- return BKE_packedfile_new_from_memory(mem, builtin_font_size);
- }
+ memcpy(mem, builtin_font_data, builtin_font_size);
+
+ return BKE_packedfile_new_from_memory(mem, builtin_font_size);
}
static VFontData *vfont_get_data(VFont *vfont)
@@ -621,12 +620,11 @@ int BKE_vfont_select_get(Object *ob, int *r_start, int *r_end)
if (start == end + 1) {
return 0;
}
- else {
- BLI_assert(start < end + 1);
- *r_start = start;
- *r_end = end;
- return direction;
- }
+
+ BLI_assert(start < end + 1);
+ *r_start = start;
+ *r_end = end;
+ return direction;
}
void BKE_vfont_select_clamp(Object *ob)
@@ -647,12 +645,11 @@ static float char_width(Curve *cu, VChar *che, CharInfo *info)
if (che == NULL) {
return 0.0f;
}
- else if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
+ if (info->flag & CU_CHINFO_SMALLCAPS_CHECK) {
return che->width * cu->smallcaps_scale;
}
- else {
- return che->width;
- }
+
+ return che->width;
}
static void textbox_scale(TextBox *tb_dst, const TextBox *tb_src, float scale)
@@ -797,7 +794,7 @@ static bool vfont_to_curve(Object *ob,
}
else {
char32_t *mem_tmp;
- slen = cu->len_wchar;
+ slen = cu->len_char32;
/* Create unicode string */
mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(*mem_tmp), "convertedmem");
@@ -1603,32 +1600,32 @@ static bool vfont_to_curve(Object *ob,
}
return true;
}
+
+ ok = true;
+finally:
+ if (r_text) {
+ *r_text = mem;
+ *r_text_len = slen;
+ *r_text_free = (ef == NULL);
+ }
else {
- ok = true;
- finally:
- if (r_text) {
- *r_text = mem;
- *r_text_len = slen;
- *r_text_free = (ef == NULL);
+ if (ef == NULL) {
+ MEM_freeN((void *)mem);
+ }
+ }
+
+ if (chartransdata) {
+ if (ok && r_chartransdata) {
+ *r_chartransdata = chartransdata;
}
else {
- if (ef == NULL) {
- MEM_freeN((void *)mem);
- }
+ MEM_freeN(chartransdata);
}
+ }
- if (chartransdata) {
- if (ok && r_chartransdata) {
- *r_chartransdata = chartransdata;
- }
- else {
- MEM_freeN(chartransdata);
- }
- }
+ /* Store the effective scale, to use for the textbox lines. */
+ cu->fsize_realtime = font_size;
- /* Store the effective scale, to use for the textbox lines. */
- cu->fsize_realtime = font_size;
- }
return ok;
#undef MARGIN_X_MIN
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index eeb55c44d6e..c64f1b86eab 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -381,7 +381,7 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
/* no layer */
return NULL;
}
- else if (gpl->actframe == NULL) {
+ if (gpl->actframe == NULL) {
/* no active frame, so just create a new one from scratch */
return BKE_gpencil_frame_addnew(gpl, cframe);
}
@@ -398,7 +398,7 @@ bGPDframe *BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
found = true;
break;
}
- else if (gpf->framenum == cframe) {
+ if (gpf->framenum == cframe) {
/* This only happens when we're editing with framelock on...
* - Delete the new frame and don't do anything else here...
*/
@@ -1009,7 +1009,7 @@ bGPDframe *BKE_gpencil_layer_frame_get(bGPDlayer *gpl, int cframe, eGP_GetFrame_
found = true;
break;
}
- else if ((gpf->next) && (gpf->next->framenum > cframe)) {
+ if ((gpf->next) && (gpf->next->framenum > cframe)) {
found = true;
break;
}
@@ -1484,10 +1484,9 @@ Material *BKE_gpencil_object_material_ensure_from_brush(Main *bmain, Object *ob,
return ma;
}
- else {
- /* using active material instead */
- return BKE_object_material_get(ob, ob->actcol);
- }
+
+ /* using active material instead */
+ return BKE_object_material_get(ob, ob->actcol);
}
/**
@@ -1546,9 +1545,8 @@ Material *BKE_gpencil_object_material_from_brush_get(Object *ob, Brush *brush)
Material *ma = BKE_gpencil_brush_material_get(brush);
return ma;
}
- else {
- return BKE_object_material_get(ob, ob->actcol);
- }
+
+ return BKE_object_material_get(ob, ob->actcol);
}
/**
@@ -1562,9 +1560,8 @@ int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) {
return BKE_gpencil_object_material_index_get(ob, brush->gpencil_settings->material);
}
- else {
- return ob->actcol - 1;
- }
+
+ return ob->actcol - 1;
}
/**
@@ -1581,9 +1578,8 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main
return BKE_gpencil_object_material_ensure_from_active_input_brush(
bmain, ob, ts->gp_paint->paint.brush);
}
- else {
- return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL);
- }
+
+ return BKE_gpencil_object_material_ensure_from_active_input_brush(bmain, ob, NULL);
}
/**
@@ -1602,7 +1598,7 @@ Material *BKE_gpencil_object_material_ensure_from_active_input_brush(Main *bmain
if (ma) {
return ma;
}
- else if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
+ if (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED) {
/* it is easier to just unpin a NULL material, instead of setting a new one */
brush->gpencil_settings->flag &= ~GP_BRUSH_MATERIAL_PINNED;
}
@@ -2425,31 +2421,29 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
unit_m4(diff_mat);
return;
}
- else {
- if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
- mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
+
+ if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) {
+ mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
+ add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
+ return;
+ }
+ if (gpl->partype == PARBONE) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr);
+ if (pchan) {
+ float tmp_mat[4][4];
+ mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat);
+ mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
- return;
- }
- else if (gpl->partype == PARBONE) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr);
- if (pchan) {
- float tmp_mat[4][4];
- mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat);
- mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
- add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
- }
- else {
- /* if bone not found use object (armature) */
- mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
- add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
- }
- return;
}
else {
- unit_m4(diff_mat); /* not defined type */
+ /* if bone not found use object (armature) */
+ mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
+ add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
}
+ return;
}
+
+ unit_m4(diff_mat); /* not defined type */
}
/**
diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c
index a7adbed6c4b..3e568bd5e1e 100644
--- a/source/blender/blenkernel/intern/gpencil_curve.c
+++ b/source/blender/blenkernel/intern/gpencil_curve.c
@@ -50,7 +50,7 @@
#include "DEG_depsgraph_query.h"
/* Helper: Check materials with same color. */
-static int gpencil_check_same_material_color(Object *ob_gp, float color[4], Material **r_mat)
+static int gpencil_check_same_material_color(Object *ob_gp, const float color[4], Material **r_mat)
{
Material *ma = NULL;
float color_cu[4];
diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c
index 579ebc9b9b3..672d65f1585 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.c
+++ b/source/blender/blenkernel/intern/gpencil_geom.c
@@ -245,24 +245,23 @@ static int stroke_march_next_point(const bGPDstroke *gps,
return 0;
}
- else {
- float ratio = remaining_march / remaining_till_next;
- interp_v3_v3v3(result, step_start, point, ratio);
- *pressure = interpf(
- gps->points[next_point_index].pressure, gps->points[next_point_index - 1].pressure, ratio);
- *strength = interpf(
- gps->points[next_point_index].strength, gps->points[next_point_index - 1].strength, ratio);
- interp_v4_v4v4(vert_color,
- gps->points[next_point_index - 1].vert_color,
- gps->points[next_point_index].vert_color,
- ratio);
-
- *index_from = next_point_index - 1;
- *index_to = next_point_index;
- *ratio_result = ratio;
- return next_point_index;
- }
+ float ratio = remaining_march / remaining_till_next;
+ interp_v3_v3v3(result, step_start, point, ratio);
+ *pressure = interpf(
+ gps->points[next_point_index].pressure, gps->points[next_point_index - 1].pressure, ratio);
+ *strength = interpf(
+ gps->points[next_point_index].strength, gps->points[next_point_index - 1].strength, ratio);
+ interp_v4_v4v4(vert_color,
+ gps->points[next_point_index - 1].vert_color,
+ gps->points[next_point_index].vert_color,
+ ratio);
+
+ *index_from = next_point_index - 1;
+ *index_to = next_point_index;
+ *ratio_result = ratio;
+
+ return next_point_index;
}
static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
@@ -306,11 +305,10 @@ static int stroke_march_next_point_no_interp(const bGPDstroke *gps,
copy_v3_v3(result, &pt->x);
return 0;
}
- else {
- float ratio = remaining_march / remaining_till_next;
- interp_v3_v3v3(result, step_start, point, ratio);
- return next_point_index;
- }
+
+ float ratio = remaining_march / remaining_till_next;
+ interp_v3_v3v3(result, step_start, point, ratio);
+ return next_point_index;
}
static int stroke_march_count(const bGPDstroke *gps, const float dist)
@@ -1352,10 +1350,9 @@ bool BKE_gpencil_stroke_trim(bGPDstroke *gps)
if ((lambda <= 0.0f) || (lambda >= 1.0f)) {
continue;
}
- else {
- intersect = true;
- break;
- }
+
+ intersect = true;
+ break;
}
}
}
@@ -2599,10 +2596,9 @@ void BKE_gpencil_stroke_set_random_color(bGPDstroke *gps)
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
bGPDspoint *pt = &gps->points[0];
- color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->x));
- color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->y));
- color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints, pt->z));
-
+ color[0] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints / 5, pt->x + pt->z));
+ color[1] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints + pt->x, pt->y * pt->z + pt->x));
+ color[2] *= BLI_hash_int_01(BLI_hash_int_2d(gps->totpoints - pt->x, pt->z * pt->x + pt->y));
for (int i = 0; i < gps->totpoints; i++) {
pt = &gps->points[i];
copy_v4_v4(pt->vert_color, color);
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index e92bf5a4502..c2e330e8f04 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -348,9 +348,8 @@ const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType
modifier_gpencil_types[type]->name[0] != '\0') {
return modifier_gpencil_types[type];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/**
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 90761d24b73..2905bfc978a 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -202,8 +202,8 @@ BoundBox *BKE_hair_boundbox_get(Object *ob)
for (int a = 0; a < hair->totpoint; a++) {
float *co = hair_co[a];
float radius = (hair_radius) ? hair_radius[a] : 0.0f;
- float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
- float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
+ const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
+ const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
DO_MIN(co_min, min);
DO_MAX(co_max, max);
}
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 6da48195aab..bec0da750e1 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -765,9 +765,8 @@ bool BKE_icon_delete(const int icon_id)
icon_free(icon);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool BKE_icon_delete_unmanaged(const int icon_id)
@@ -783,15 +782,13 @@ bool BKE_icon_delete_unmanaged(const int icon_id)
BLI_ghash_insert(gIcons, POINTER_FROM_INT(icon_id), icon);
return false;
}
- else {
- icon_free_data(icon_id, icon);
- icon_free(icon);
- return true;
- }
- }
- else {
- return false;
+
+ icon_free_data(icon_id, icon);
+ icon_free(icon);
+ return true;
}
+
+ return false;
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index c3c67b9ed51..e394242001c 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -181,7 +181,7 @@ void IDP_ResizeIDPArray(IDProperty *prop, int newlen)
prop->len = newlen;
return;
}
- else if (newlen >= prop->len) {
+ if (newlen >= prop->len) {
prop->len = newlen;
return;
}
@@ -836,17 +836,16 @@ IDProperty *IDP_GetProperties(ID *id, const bool create_if_needed)
if (id->properties) {
return id->properties;
}
- else {
- if (create_if_needed) {
- id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty");
- id->properties->type = IDP_GROUP;
- /* don't overwrite the data's name and type
- * some functions might need this if they
- * don't have a real ID, should be named elsewhere - Campbell */
- /* strcpy(id->name, "top_level_group");*/
- }
- return id->properties;
+
+ if (create_if_needed) {
+ id->properties = MEM_callocN(sizeof(IDProperty), "IDProperty");
+ id->properties->type = IDP_GROUP;
+ /* don't overwrite the data's name and type
+ * some functions might need this if they
+ * don't have a real ID, should be named elsewhere - Campbell */
+ /* strcpy(id->name, "top_level_group");*/
}
+ return id->properties;
}
/**
@@ -856,10 +855,10 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
if (prop1 == NULL && prop2 == NULL) {
return true;
}
- else if (prop1 == NULL || prop2 == NULL) {
+ if (prop1 == NULL || prop2 == NULL) {
return is_strict ? false : true;
}
- else if (prop1->type != prop2->type) {
+ if (prop1->type != prop2->type) {
return false;
}
diff --git a/source/blender/blenkernel/intern/idtype.c b/source/blender/blenkernel/intern/idtype.c
index 1166ad9ad2f..4ab7d362e0e 100644
--- a/source/blender/blenkernel/intern/idtype.c
+++ b/source/blender/blenkernel/intern/idtype.c
@@ -135,9 +135,8 @@ const IDTypeInfo *BKE_idtype_get_info_from_idcode(const short id_code)
id_types[id_index]->name[0] != '\0') {
return id_types[id_index];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
const IDTypeInfo *BKE_idtype_get_info_from_id(const ID *id)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 9365ee040c2..4bd966cffc6 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -57,6 +57,7 @@
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_simulation_types.h"
#include "DNA_world_types.h"
#include "BLI_blenlib.h"
@@ -89,7 +90,6 @@
#include "RE_pipeline.h"
-#include "GPU_draw.h"
#include "GPU_texture.h"
#include "BLI_sys_types.h" // for intptr_t support
@@ -392,7 +392,7 @@ void BKE_image_free_buffers_ex(Image *ima, bool do_lock)
ima->rr = NULL;
}
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
tile->ok = IMA_OK;
@@ -667,9 +667,8 @@ char BKE_image_alpha_mode_from_extension_ex(const char *filepath)
if (BLI_path_extension_check_n(filepath, ".exr", ".cin", ".dpx", ".hdr", NULL)) {
return IMA_ALPHA_PREMUL;
}
- else {
- return IMA_ALPHA_STRAIGHT;
- }
+
+ return IMA_ALPHA_STRAIGHT;
}
void BKE_image_alpha_mode_from_extension(Image *image)
@@ -1201,57 +1200,56 @@ int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
if (imtype == R_IMF_IMTYPE_TARGA) {
return IMB_FTYPE_TGA;
}
- else if (imtype == R_IMF_IMTYPE_RAWTGA) {
+ if (imtype == R_IMF_IMTYPE_RAWTGA) {
r_options->flag = RAWTGA;
return IMB_FTYPE_TGA;
}
- else if (imtype == R_IMF_IMTYPE_IRIS) {
+ if (imtype == R_IMF_IMTYPE_IRIS) {
return IMB_FTYPE_IMAGIC;
}
#ifdef WITH_HDR
- else if (imtype == R_IMF_IMTYPE_RADHDR) {
+ if (imtype == R_IMF_IMTYPE_RADHDR) {
return IMB_FTYPE_RADHDR;
}
#endif
- else if (imtype == R_IMF_IMTYPE_PNG) {
+ if (imtype == R_IMF_IMTYPE_PNG) {
r_options->quality = 15;
return IMB_FTYPE_PNG;
}
#ifdef WITH_DDS
- else if (imtype == R_IMF_IMTYPE_DDS) {
+ if (imtype == R_IMF_IMTYPE_DDS) {
return IMB_FTYPE_DDS;
}
#endif
- else if (imtype == R_IMF_IMTYPE_BMP) {
+ if (imtype == R_IMF_IMTYPE_BMP) {
return IMB_FTYPE_BMP;
}
#ifdef WITH_TIFF
- else if (imtype == R_IMF_IMTYPE_TIFF) {
+ if (imtype == R_IMF_IMTYPE_TIFF) {
return IMB_FTYPE_TIF;
}
#endif
- else if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) {
+ if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) {
return IMB_FTYPE_OPENEXR;
}
#ifdef WITH_CINEON
- else if (imtype == R_IMF_IMTYPE_CINEON) {
+ if (imtype == R_IMF_IMTYPE_CINEON) {
return IMB_FTYPE_CINEON;
}
- else if (imtype == R_IMF_IMTYPE_DPX) {
+ if (imtype == R_IMF_IMTYPE_DPX) {
return IMB_FTYPE_DPX;
}
#endif
#ifdef WITH_OPENJPEG
- else if (imtype == R_IMF_IMTYPE_JP2) {
+ if (imtype == R_IMF_IMTYPE_JP2) {
r_options->flag |= JP2_JP2;
r_options->quality = 90;
return IMB_FTYPE_JP2;
}
#endif
- else {
- r_options->quality = 90;
- return IMB_FTYPE_JPG;
- }
+
+ r_options->quality = 90;
+ return IMB_FTYPE_JPG;
}
char BKE_image_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
@@ -1259,57 +1257,55 @@ char BKE_image_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
if (ftype == 0) {
return R_IMF_IMTYPE_TARGA;
}
- else if (ftype == IMB_FTYPE_IMAGIC) {
+ if (ftype == IMB_FTYPE_IMAGIC) {
return R_IMF_IMTYPE_IRIS;
}
#ifdef WITH_HDR
- else if (ftype == IMB_FTYPE_RADHDR) {
+ if (ftype == IMB_FTYPE_RADHDR) {
return R_IMF_IMTYPE_RADHDR;
}
#endif
- else if (ftype == IMB_FTYPE_PNG) {
+ if (ftype == IMB_FTYPE_PNG) {
return R_IMF_IMTYPE_PNG;
}
#ifdef WITH_DDS
- else if (ftype == IMB_FTYPE_DDS) {
+ if (ftype == IMB_FTYPE_DDS) {
return R_IMF_IMTYPE_DDS;
}
#endif
- else if (ftype == IMB_FTYPE_BMP) {
+ if (ftype == IMB_FTYPE_BMP) {
return R_IMF_IMTYPE_BMP;
}
#ifdef WITH_TIFF
- else if (ftype == IMB_FTYPE_TIF) {
+ if (ftype == IMB_FTYPE_TIF) {
return R_IMF_IMTYPE_TIFF;
}
#endif
- else if (ftype == IMB_FTYPE_OPENEXR) {
+ if (ftype == IMB_FTYPE_OPENEXR) {
return R_IMF_IMTYPE_OPENEXR;
}
#ifdef WITH_CINEON
- else if (ftype == IMB_FTYPE_CINEON) {
+ if (ftype == IMB_FTYPE_CINEON) {
return R_IMF_IMTYPE_CINEON;
}
- else if (ftype == IMB_FTYPE_DPX) {
+ if (ftype == IMB_FTYPE_DPX) {
return R_IMF_IMTYPE_DPX;
}
#endif
- else if (ftype == IMB_FTYPE_TGA) {
+ if (ftype == IMB_FTYPE_TGA) {
if (options && (options->flag & RAWTGA)) {
return R_IMF_IMTYPE_RAWTGA;
}
- else {
- return R_IMF_IMTYPE_TARGA;
- }
+
+ return R_IMF_IMTYPE_TARGA;
}
#ifdef WITH_OPENJPEG
- else if (ftype == IMB_FTYPE_JP2) {
+ if (ftype == IMB_FTYPE_JP2) {
return R_IMF_IMTYPE_JP2;
}
#endif
- else {
- return R_IMF_IMTYPE_JPEG90;
- }
+
+ return R_IMF_IMTYPE_JPEG90;
}
bool BKE_imtype_is_movie(const char imtype)
@@ -1443,78 +1439,77 @@ char BKE_imtype_from_arg(const char *imtype_arg)
if (STREQ(imtype_arg, "TGA")) {
return R_IMF_IMTYPE_TARGA;
}
- else if (STREQ(imtype_arg, "IRIS")) {
+ if (STREQ(imtype_arg, "IRIS")) {
return R_IMF_IMTYPE_IRIS;
}
#ifdef WITH_DDS
- else if (STREQ(imtype_arg, "DDS")) {
+ if (STREQ(imtype_arg, "DDS")) {
return R_IMF_IMTYPE_DDS;
}
#endif
- else if (STREQ(imtype_arg, "JPEG")) {
+ if (STREQ(imtype_arg, "JPEG")) {
return R_IMF_IMTYPE_JPEG90;
}
- else if (STREQ(imtype_arg, "IRIZ")) {
+ if (STREQ(imtype_arg, "IRIZ")) {
return R_IMF_IMTYPE_IRIZ;
}
- else if (STREQ(imtype_arg, "RAWTGA")) {
+ if (STREQ(imtype_arg, "RAWTGA")) {
return R_IMF_IMTYPE_RAWTGA;
}
- else if (STREQ(imtype_arg, "AVIRAW")) {
+ if (STREQ(imtype_arg, "AVIRAW")) {
return R_IMF_IMTYPE_AVIRAW;
}
- else if (STREQ(imtype_arg, "AVIJPEG")) {
+ if (STREQ(imtype_arg, "AVIJPEG")) {
return R_IMF_IMTYPE_AVIJPEG;
}
- else if (STREQ(imtype_arg, "PNG")) {
+ if (STREQ(imtype_arg, "PNG")) {
return R_IMF_IMTYPE_PNG;
}
- else if (STREQ(imtype_arg, "BMP")) {
+ if (STREQ(imtype_arg, "BMP")) {
return R_IMF_IMTYPE_BMP;
}
#ifdef WITH_HDR
- else if (STREQ(imtype_arg, "HDR")) {
+ if (STREQ(imtype_arg, "HDR")) {
return R_IMF_IMTYPE_RADHDR;
}
#endif
#ifdef WITH_TIFF
- else if (STREQ(imtype_arg, "TIFF")) {
+ if (STREQ(imtype_arg, "TIFF")) {
return R_IMF_IMTYPE_TIFF;
}
#endif
#ifdef WITH_OPENEXR
- else if (STREQ(imtype_arg, "OPEN_EXR")) {
+ if (STREQ(imtype_arg, "OPEN_EXR")) {
return R_IMF_IMTYPE_OPENEXR;
}
- else if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) {
+ if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) {
return R_IMF_IMTYPE_MULTILAYER;
}
- else if (STREQ(imtype_arg, "EXR")) {
+ if (STREQ(imtype_arg, "EXR")) {
return R_IMF_IMTYPE_OPENEXR;
}
- else if (STREQ(imtype_arg, "MULTILAYER")) {
+ if (STREQ(imtype_arg, "MULTILAYER")) {
return R_IMF_IMTYPE_MULTILAYER;
}
#endif
- else if (STREQ(imtype_arg, "FFMPEG")) {
+ if (STREQ(imtype_arg, "FFMPEG")) {
return R_IMF_IMTYPE_FFMPEG;
}
#ifdef WITH_CINEON
- else if (STREQ(imtype_arg, "CINEON")) {
+ if (STREQ(imtype_arg, "CINEON")) {
return R_IMF_IMTYPE_CINEON;
}
- else if (STREQ(imtype_arg, "DPX")) {
+ if (STREQ(imtype_arg, "DPX")) {
return R_IMF_IMTYPE_DPX;
}
#endif
#ifdef WITH_OPENJPEG
- else if (STREQ(imtype_arg, "JP2")) {
+ if (STREQ(imtype_arg, "JP2")) {
return R_IMF_IMTYPE_JP2;
}
#endif
- else {
- return R_IMF_IMTYPE_INVALID;
- }
+
+ return R_IMF_IMTYPE_INVALID;
}
static bool do_add_image_extension(char *string,
@@ -1638,13 +1633,11 @@ static bool do_add_image_extension(char *string,
if (BLI_path_extension_check_array(string, imb_ext_image)) {
return BLI_path_extension_replace(string, FILE_MAX, extension);
}
- else {
- return BLI_path_extension_ensure(string, FILE_MAX, extension);
- }
- }
- else {
- return false;
+
+ return BLI_path_extension_ensure(string, FILE_MAX, extension);
}
+
+ return false;
}
int BKE_image_path_ensure_ext_from_imformat(char *string, const ImageFormatData *im_format)
@@ -3240,6 +3233,12 @@ static void image_walk_id_all_users(
if (scene->nodetree && scene->use_nodes && !skip_nested_nodes) {
image_walk_ntree_all_users(scene->nodetree, &scene->id, customdata, callback);
}
+ break;
+ }
+ case ID_SIM: {
+ Simulation *simulation = (Simulation *)id;
+ image_walk_ntree_all_users(simulation->nodetree, &simulation->id, customdata, callback);
+ break;
}
default:
break;
@@ -3344,8 +3343,7 @@ static void image_free_tile(Image *ima, ImageTile *tile)
for (int i = 0; i < TEXTARGET_COUNT; i++) {
/* Only two textures depends on all tiles, so if this is a secondary tile we can keep the other
* two. */
- if (tile != ima->tiles.first &&
- !(ELEM(i, TEXTARGET_TEXTURE_2D_ARRAY, TEXTARGET_TEXTURE_TILE_MAPPING))) {
+ if (tile != ima->tiles.first && !(ELEM(i, TEXTARGET_2D_ARRAY, TEXTARGET_TILE_MAPPING))) {
continue;
}
@@ -3543,9 +3541,8 @@ static RenderPass *image_render_pass_get(RenderLayer *rl,
/* no multiview or left eye */
break;
}
- else {
- rp_name = rpass->name;
- }
+
+ rp_name = rpass->name;
}
/* multiview */
else if (rp_name[0] && STREQ(rpass->name, rp_name) && (rpass->view_id == view)) {
@@ -3622,13 +3619,13 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
for (int eye = 0; eye < 2; eye++) {
/* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
+ ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL;
}
- if (ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][eye] = NULL;
+ if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
+ ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL;
}
}
@@ -3708,9 +3705,8 @@ RenderPass *BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
iuser->multi_index = index + rp_index;
break;
}
- else {
- index += BLI_listbase_count(&rl->passes);
- }
+
+ index += BLI_listbase_count(&rl->passes);
}
}
@@ -3937,7 +3933,7 @@ static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
#endif /* WITH_OPENEXR */
/* common stuff to do with images after loading */
-static void image_initialize_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
+static void image_init_after_load(Image *ima, ImageUser *iuser, ImBuf *UNUSED(ibuf))
{
/* Preview is NULL when it has never been used as an icon before.
* Never handle previews/icons outside of main thread. */
@@ -3981,13 +3977,12 @@ static int image_num_files(Image *ima)
if (!is_multiview) {
return 1;
}
- else if (ima->views_format == R_IMF_VIEWS_STEREO_3D) {
+ if (ima->views_format == R_IMF_VIEWS_STEREO_3D) {
return 1;
}
/* R_IMF_VIEWS_INDIVIDUAL */
- else {
- return BLI_listbase_count(&ima->views);
- }
+
+ return BLI_listbase_count(&ima->views);
}
static ImBuf *load_sequence_single(
@@ -4040,11 +4035,11 @@ static ImBuf *load_sequence_single(
}
}
else {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
}
#else
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
#endif
}
@@ -4149,7 +4144,7 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int e
BKE_imbuf_stamp_info(ima->rr, ibuf);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, entry);
}
// else printf("pass not found\n");
@@ -4213,7 +4208,7 @@ static ImBuf *load_movie_single(Image *ima, ImageUser *iuser, int frame, const i
ibuf = IMB_makeSingleUser(IMB_anim_absolute(ia->anim, fra, IMB_TC_RECORD_RUN, IMB_PROXY_NONE));
if (ibuf) {
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
}
else {
tile->ok = 0;
@@ -4358,7 +4353,7 @@ static ImBuf *load_image_single(Image *ima,
else
#endif
{
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
*r_assign = true;
/* make packed file for autopack */
@@ -4472,7 +4467,7 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
if (rpass) {
ibuf = IMB_allocImBuf(ima->rr->rectx, ima->rr->recty, 32, 0);
- image_initialize_after_load(ima, iuser, ibuf);
+ image_init_after_load(ima, iuser, ibuf);
ibuf->rect_float = rpass->rect;
ibuf->flags |= IB_rectfloat;
@@ -4702,7 +4697,7 @@ static int image_get_multiview_index(Image *ima, ImageUser *iuser)
if (is_multilayer) {
return iuser ? iuser->multi_index : index;
}
- else if (is_backdrop) {
+ if (is_backdrop) {
if (BKE_image_is_stereo(ima)) {
/* backdrop hackaround (since there is no iuser */
return ima->eye;
@@ -4839,7 +4834,7 @@ BLI_INLINE bool image_quick_test(Image *ima, const ImageUser *iuser)
if (tile == NULL) {
return false;
}
- else if (tile->ok == 0) {
+ if (tile->ok == 0) {
return false;
}
@@ -5156,58 +5151,57 @@ int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, bool *r_is_in_ran
if (len == 0) {
return 0;
}
- else {
- int framenr;
- cfra = cfra - iuser->sfra + 1;
-
- /* cyclic */
- if (iuser->cycl) {
- cfra = ((cfra) % len);
- if (cfra < 0) {
- cfra += len;
- }
- if (cfra == 0) {
- cfra = len;
- }
- if (r_is_in_range) {
- *r_is_in_range = true;
- }
- }
+ int framenr;
+ cfra = cfra - iuser->sfra + 1;
+ /* cyclic */
+ if (iuser->cycl) {
+ cfra = ((cfra) % len);
if (cfra < 0) {
- cfra = 0;
+ cfra += len;
}
- else if (cfra > len) {
+ if (cfra == 0) {
cfra = len;
}
- else {
- if (r_is_in_range) {
- *r_is_in_range = true;
- }
- }
- /* transform to images space */
- framenr = cfra;
- if (framenr > iuser->frames) {
- framenr = iuser->frames;
+ if (r_is_in_range) {
+ *r_is_in_range = true;
}
+ }
- if (iuser->cycl) {
- framenr = ((framenr) % len);
- while (framenr < 0) {
- framenr += len;
- }
- if (framenr == 0) {
- framenr = len;
- }
+ if (cfra < 0) {
+ cfra = 0;
+ }
+ else if (cfra > len) {
+ cfra = len;
+ }
+ else {
+ if (r_is_in_range) {
+ *r_is_in_range = true;
}
+ }
- /* important to apply after else we cant loop on frames 100 - 110 for eg. */
- framenr += iuser->offset;
+ /* transform to images space */
+ framenr = cfra;
+ if (framenr > iuser->frames) {
+ framenr = iuser->frames;
+ }
- return framenr;
+ if (iuser->cycl) {
+ framenr = ((framenr) % len);
+ while (framenr < 0) {
+ framenr += len;
+ }
+ if (framenr == 0) {
+ framenr = len;
+ }
}
+
+ /* important to apply after else we cant loop on frames 100 - 110 for eg. */
+ framenr += iuser->offset;
+
+ return framenr;
}
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
@@ -5373,9 +5367,8 @@ bool BKE_image_has_alpha(struct Image *image)
if (planes == 32) {
return true;
}
- else {
- return false;
- }
+
+ return false;
}
void BKE_image_get_size(Image *image, ImageUser *iuser, int *r_width, int *r_height)
@@ -5841,17 +5834,16 @@ bool BKE_image_clear_renderslot(Image *ima, ImageUser *iuser, int index)
RE_ClearResult(re);
return true;
}
- else {
- RenderSlot *slot = BLI_findlink(&ima->renderslots, index);
- if (!slot) {
- return false;
- }
- if (slot->render) {
- RE_FreeRenderResult(slot->render);
- slot->render = NULL;
- }
- return true;
+
+ RenderSlot *slot = BLI_findlink(&ima->renderslots, index);
+ if (!slot) {
+ return false;
}
+ if (slot->render) {
+ RE_FreeRenderResult(slot->render);
+ slot->render = NULL;
+ }
+ return true;
}
RenderSlot *BKE_image_get_renderslot(Image *ima, int index)
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
new file mode 100644
index 00000000000..22fb6dfd02a
--- /dev/null
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -0,0 +1,774 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_boxpack_2d.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
+
+#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "BKE_global.h"
+#include "BKE_image.h"
+#include "BKE_main.h"
+
+#include "GPU_extensions.h"
+#include "GPU_state.h"
+#include "GPU_texture.h"
+
+#include "PIL_time.h"
+
+/* Prototypes. */
+static void gpu_free_unused_buffers(void);
+static void image_free_gpu(Image *ima, const bool immediate);
+
+/* -------------------------------------------------------------------- */
+/** \name UDIM gpu texture
+ * \{ */
+
+static bool is_over_resolution_limit(int w, int h)
+{
+ return (w > GPU_texture_size_with_limit(w) || h > GPU_texture_size_with_limit(h));
+}
+
+static int smaller_power_of_2_limit(int num)
+{
+ return power_of_2_min_i(GPU_texture_size_with_limit(num));
+}
+
+static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
+{
+ GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye];
+
+ if (tilearray == NULL) {
+ return 0;
+ }
+
+ float array_w = GPU_texture_width(tilearray);
+ float array_h = GPU_texture_height(tilearray);
+
+ ImageTile *last_tile = (ImageTile *)ima->tiles.last;
+ /* Tiles are sorted by number. */
+ int max_tile = last_tile->tile_number - 1001;
+
+ /* create image */
+ int width = max_tile + 1;
+ float *data = (float *)MEM_callocN(width * 8 * sizeof(float), __func__);
+ for (int i = 0; i < width; i++) {
+ data[4 * i] = -1.0f;
+ }
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int i = tile->tile_number - 1001;
+ data[4 * i] = tile->runtime.tilearray_layer;
+
+ float *tile_info = &data[4 * width + 4 * i];
+ tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
+ tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
+ tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
+ tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
+ }
+
+ GPUTexture *tex = GPU_texture_create_1d_array(width, 2, GPU_RGBA32F, data, NULL);
+ GPU_texture_mipmap_mode(tex, false, false);
+
+ MEM_freeN(data);
+
+ return tex;
+}
+
+typedef struct PackTile {
+ FixedSizeBoxPack boxpack;
+ ImageTile *tile;
+ float pack_score;
+} PackTile;
+
+static int compare_packtile(const void *a, const void *b)
+{
+ const PackTile *tile_a = (const PackTile *)a;
+ const PackTile *tile_b = (const PackTile *)b;
+
+ return tile_a->pack_score < tile_b->pack_score;
+}
+
+static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
+{
+ int arraywidth = 0, arrayheight = 0;
+ ListBase boxes = {NULL};
+
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ PackTile *packtile = (PackTile *)MEM_callocN(sizeof(PackTile), __func__);
+ packtile->tile = tile;
+ packtile->boxpack.w = ibuf->x;
+ packtile->boxpack.h = ibuf->y;
+
+ if (is_over_resolution_limit(packtile->boxpack.w, packtile->boxpack.h)) {
+ packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w);
+ packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h);
+ }
+ arraywidth = max_ii(arraywidth, packtile->boxpack.w);
+ arrayheight = max_ii(arrayheight, packtile->boxpack.h);
+
+ /* We sort the tiles by decreasing size, with an additional penalty term
+ * for high aspect ratios. This improves packing efficiency. */
+ float w = packtile->boxpack.w, h = packtile->boxpack.h;
+ packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ BLI_addtail(&boxes, packtile);
+ }
+ }
+
+ BLI_assert(arraywidth > 0 && arrayheight > 0);
+
+ BLI_listbase_sort(&boxes, compare_packtile);
+ int arraylayers = 0;
+ /* Keep adding layers until all tiles are packed. */
+ while (boxes.first != NULL) {
+ ListBase packed = {NULL};
+ BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed);
+ BLI_assert(packed.first != NULL);
+
+ LISTBASE_FOREACH (PackTile *, packtile, &packed) {
+ ImageTile *tile = packtile->tile;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ tileoffset[0] = packtile->boxpack.x;
+ tileoffset[1] = packtile->boxpack.y;
+ tilesize[0] = packtile->boxpack.w;
+ tilesize[1] = packtile->boxpack.h;
+ tile->runtime.tilearray_layer = arraylayers;
+ }
+
+ BLI_freelistN(&packed);
+ arraylayers++;
+ }
+
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ /* Create Texture without content. */
+ GPUTexture *tex = IMB_touch_gpu_texture(
+ main_ibuf, arraywidth, arrayheight, arraylayers, use_high_bitdepth);
+
+ GPU_texture_bind(tex, 0);
+
+ /* Upload each tile one by one. */
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ int tilelayer = tile->runtime.tilearray_layer;
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+
+ if (tilesize[0] == 0 || tilesize[1] == 0) {
+ continue;
+ }
+
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf) {
+ const bool store_premultiplied = ibuf->rect_float ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) :
+ (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_update_gpu_texture_sub(tex,
+ ibuf,
+ UNPACK2(tileoffset),
+ tilelayer,
+ UNPACK2(tilesize),
+ use_high_bitdepth,
+ store_premultiplied);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ GPU_texture_mipmap_mode(tex, true, true);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+ else {
+ GPU_texture_mipmap_mode(tex, false, true);
+ }
+
+ GPU_texture_unbind(tex);
+
+ return tex;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Regular gpu texture
+ * \{ */
+
+static GPUTexture **get_image_gpu_texture_ptr(Image *ima,
+ eGPUTextureTarget textarget,
+ const int multiview_eye)
+{
+ const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT);
+ BLI_assert(in_range);
+
+ if (in_range) {
+ return &(ima->gputexture[textarget][multiview_eye]);
+ }
+ return NULL;
+}
+
+static GPUTexture *image_gpu_texture_error_create(eGPUTextureTarget textarget)
+{
+ switch (textarget) {
+ case TEXTARGET_2D_ARRAY:
+ return GPU_texture_create_error(2, true);
+ case TEXTARGET_TILE_MAPPING:
+ return GPU_texture_create_error(1, true);
+ case TEXTARGET_2D:
+ default:
+ return GPU_texture_create_error(2, false);
+ }
+}
+
+static GPUTexture *image_get_gpu_texture(Image *ima,
+ ImageUser *iuser,
+ ImBuf *ibuf,
+ eGPUTextureTarget textarget)
+{
+ if (ima == NULL) {
+ return NULL;
+ }
+
+ /* Free any unused GPU textures, since we know we are in a thread with OpenGL
+ * context and might as well ensure we have as much space free as possible. */
+ gpu_free_unused_buffers();
+
+ /* currently, gpu refresh tagging is used by ima sequences */
+ if (ima->gpuflag & IMA_GPU_REFRESH) {
+ image_free_gpu(ima, true);
+ ima->gpuflag &= ~IMA_GPU_REFRESH;
+ }
+
+ /* Tag as in active use for garbage collector. */
+ BKE_image_tag_time(ima);
+
+ /* Test if we already have a texture. */
+ GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, iuser ? iuser->multiview_eye : 0);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* Check if we have a valid image. If not, we return a dummy
+ * texture with zero bind-code so we don't keep trying. */
+ ImageTile *tile = BKE_image_get_tile(ima, 0);
+ if (tile == NULL || tile->ok == 0) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf_intern = ibuf;
+ if (ibuf_intern == NULL) {
+ ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if (ibuf_intern == NULL) {
+ *tex = image_gpu_texture_error_create(textarget);
+ return *tex;
+ }
+ }
+
+ if (textarget == TEXTARGET_2D_ARRAY) {
+ *tex = gpu_texture_create_tile_array(ima, ibuf_intern);
+ }
+ else if (textarget == TEXTARGET_TILE_MAPPING) {
+ *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
+ }
+ else {
+ const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
+ const bool store_premultiplied = ibuf_intern->rect_float ?
+ (ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false) :
+ (ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true);
+
+ *tex = IMB_create_gpu_texture(ibuf_intern, use_high_bitdepth, store_premultiplied);
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_bind(*tex, 0);
+ GPU_texture_generate_mipmap(*tex);
+ GPU_texture_unbind(*tex);
+ if (ima) {
+ ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
+ }
+ GPU_texture_mipmap_mode(*tex, true, true);
+ }
+ else {
+ GPU_texture_mipmap_mode(*tex, false, true);
+ }
+ }
+
+ /* if `ibuf` was given, we don't own the `ibuf_intern` */
+ if (ibuf == NULL) {
+ BKE_image_release_ibuf(ima, ibuf_intern, NULL);
+ }
+
+ GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y);
+
+ return *tex;
+}
+
+GPUTexture *BKE_image_get_gpu_texture(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D);
+}
+
+GPUTexture *BKE_image_get_gpu_tiles(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_2D_ARRAY);
+}
+
+GPUTexture *BKE_image_get_gpu_tilemap(Image *image, ImageUser *iuser, ImBuf *ibuf)
+{
+ return image_get_gpu_texture(image, iuser, ibuf, TEXTARGET_TILE_MAPPING);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Delayed GPU texture free
+ *
+ * Image datablocks can be deleted by any thread, but there may not be any active OpenGL context.
+ * In that case we push them into a queue and free the buffers later.
+ * \{ */
+
+static LinkNode *gpu_texture_free_queue = NULL;
+static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
+
+static void gpu_free_unused_buffers(void)
+{
+ if (gpu_texture_free_queue == NULL) {
+ return;
+ }
+
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+
+ while (gpu_texture_free_queue != NULL) {
+ GPUTexture *tex = BLI_linklist_pop(&gpu_texture_free_queue);
+ GPU_texture_free(tex);
+ }
+
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+}
+
+void BKE_image_free_unused_gpu_textures()
+{
+ if (BLI_thread_is_main()) {
+ gpu_free_unused_buffers();
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Deletion
+ * \{ */
+
+static void image_free_gpu(Image *ima, const bool immediate)
+{
+ for (int eye = 0; eye < 2; eye++) {
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ if (ima->gputexture[i][eye] != NULL) {
+ if (immediate) {
+ GPU_texture_free(ima->gputexture[i][eye]);
+ }
+ else {
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+ BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ }
+
+ ima->gputexture[i][eye] = NULL;
+ }
+ }
+ }
+
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+}
+
+void BKE_image_free_gputextures(Image *ima)
+{
+ image_free_gpu(ima, BLI_thread_is_main());
+}
+
+void BKE_image_free_all_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+}
+
+/* same as above but only free animated images */
+void BKE_image_free_anim_gputextures(Main *bmain)
+{
+ if (bmain) {
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_is_animated(ima)) {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ }
+}
+
+void BKE_image_free_old_gputextures(Main *bmain)
+{
+ static int lasttime = 0;
+ int ctime = (int)PIL_check_seconds_timer();
+
+ /*
+ * Run garbage collector once for every collecting period of time
+ * if textimeout is 0, that's the option to NOT run the collector
+ */
+ if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) {
+ return;
+ }
+
+ /* of course not! */
+ if (G.is_rendering) {
+ return;
+ }
+
+ lasttime = ctime;
+
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
+ /* If it's in GL memory, deallocate and set time tag to current time
+ * This gives textures a "second chance" to be used before dying. */
+ if (BKE_image_has_opengl_texture(ima)) {
+ BKE_image_free_gputextures(ima);
+ ima->lastused = ctime;
+ }
+ /* Otherwise, just kill the buffers */
+ else {
+ BKE_image_free_buffers(ima);
+ }
+ }
+ }
+}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Paint Update
+ * \{ */
+
+static ImBuf *update_do_scale(uchar *rect,
+ float *rect_float,
+ int *x,
+ int *y,
+ int *w,
+ int *h,
+ int limit_w,
+ int limit_h,
+ int full_w,
+ int full_h)
+{
+ /* Partial update with scaling. */
+ float xratio = limit_w / (float)full_w;
+ float yratio = limit_h / (float)full_h;
+
+ int part_w = *w, part_h = *h;
+
+ /* Find sub coordinates in scaled image. Take ceiling because we will be
+ * losing 1 pixel due to rounding errors in x,y. */
+ *x *= xratio;
+ *y *= yratio;
+ *w = (int)ceil(xratio * (*w));
+ *h = (int)ceil(yratio * (*h));
+
+ /* ...but take back if we are over the limit! */
+ if (*x + *w > limit_w) {
+ (*w)--;
+ }
+ if (*y + *h > limit_h) {
+ (*h)--;
+ }
+
+ /* Scale pixels. */
+ ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
+ IMB_scaleImBuf(ibuf, *w, *h);
+
+ return ibuf;
+}
+
+static void gpu_texture_update_scaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int full_w,
+ int full_h,
+ int x,
+ int y,
+ int layer,
+ const int *tile_offset,
+ const int *tile_size,
+ int w,
+ int h)
+{
+ ImBuf *ibuf;
+ if (layer > -1) {
+ ibuf = update_do_scale(
+ rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h);
+
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+ else {
+ /* Partial update with scaling. */
+ int limit_w = smaller_power_of_2_limit(full_w);
+ int limit_h = smaller_power_of_2_limit(full_h);
+
+ ibuf = update_do_scale(rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
+ }
+
+ void *data = (ibuf->rect_float) ? (void *)(ibuf->rect_float) : (void *)(ibuf->rect);
+ eGPUDataFormat data_format = (ibuf->rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+
+ IMB_freeImBuf(ibuf);
+}
+
+static void gpu_texture_update_unscaled(GPUTexture *tex,
+ uchar *rect,
+ float *rect_float,
+ int x,
+ int y,
+ int layer,
+ const int tile_offset[2],
+ int w,
+ int h,
+ int tex_stride,
+ int tex_offset)
+{
+ if (layer > -1) {
+ /* Shift to account for tile packing. */
+ x += tile_offset[0];
+ y += tile_offset[1];
+ }
+
+ void *data = (rect_float) ? (void *)(rect_float + tex_offset) : (void *)(rect + tex_offset);
+ eGPUDataFormat data_format = (rect_float) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ /* Partial update without scaling. Stride and offset are used to copy only a
+ * subset of a possible larger buffer than what we are updating. */
+ GPU_unpack_row_length_set(tex_stride);
+
+ GPU_texture_update_sub(tex, data_format, data, x, y, layer, w, h, 1);
+ /* Restore default. */
+ GPU_unpack_row_length_set(0);
+}
+
+static void gpu_texture_update_from_ibuf(
+ GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
+{
+ bool scaled;
+ if (tile != NULL) {
+ int *tilesize = tile->runtime.tilearray_size;
+ scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
+ }
+ else {
+ scaled = is_over_resolution_limit(ibuf->x, ibuf->y);
+ }
+
+ if (scaled) {
+ /* Extra padding to account for bleed from neighboring pixels. */
+ const int padding = 4;
+ const int xmax = min_ii(x + w + padding, ibuf->x);
+ const int ymax = min_ii(y + h + padding, ibuf->y);
+ x = max_ii(x - padding, 0);
+ y = max_ii(y - padding, 0);
+ w = xmax - x;
+ h = ymax - y;
+ }
+
+ /* Get texture data pointers. */
+ float *rect_float = ibuf->rect_float;
+ uchar *rect = (uchar *)ibuf->rect;
+ int tex_stride = ibuf->x;
+ int tex_offset = ibuf->channels * (y * ibuf->x + x);
+
+ if (rect_float == NULL) {
+ /* Byte pixels. */
+ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
+ const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(
+ ibuf->rect_colorspace);
+
+ rect = (uchar *)MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__);
+ if (rect == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ /* Convert to scene linear with sRGB compression, and premultiplied for
+ * correct texture interpolation. */
+ const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
+ IMB_colormanagement_imbuf_to_byte_texture(
+ rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
+ }
+ }
+ else {
+ /* Float pixels. */
+ const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
+
+ if (ibuf->channels != 4 || scaled || !store_premultiplied) {
+ rect_float = (float *)MEM_mallocN(sizeof(float) * 4 * w * h, __func__);
+ if (rect_float == NULL) {
+ return;
+ }
+
+ tex_stride = w;
+ tex_offset = 0;
+
+ IMB_colormanagement_imbuf_to_float_texture(
+ rect_float, x, y, w, h, ibuf, store_premultiplied);
+ }
+ }
+
+ GPU_texture_bind(tex, 0);
+
+ if (scaled) {
+ /* Slower update where we first have to scale the input pixels. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int *tilesize = tile->runtime.tilearray_size;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
+ }
+ else {
+ gpu_texture_update_scaled(
+ tex, rect, rect_float, ibuf->x, ibuf->y, x, y, -1, NULL, NULL, w, h);
+ }
+ }
+ else {
+ /* Fast update at same resolution. */
+ if (tile != NULL) {
+ int *tileoffset = tile->runtime.tilearray_offset;
+ int tilelayer = tile->runtime.tilearray_layer;
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, tilelayer, tileoffset, w, h, tex_stride, tex_offset);
+ }
+ else {
+ gpu_texture_update_unscaled(
+ tex, rect, rect_float, x, y, -1, NULL, w, h, tex_stride, tex_offset);
+ }
+ }
+
+ /* Free buffers if needed. */
+ if (rect && rect != (uchar *)ibuf->rect) {
+ MEM_freeN(rect);
+ }
+ if (rect_float && rect_float != ibuf->rect_float) {
+ MEM_freeN(rect_float);
+ }
+
+ if (GPU_mipmap_enabled()) {
+ GPU_texture_generate_mipmap(tex);
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+
+ GPU_texture_unbind(tex);
+}
+
+/* Partial update of texture for texture painting. This is often much
+ * quicker than fully updating the texture for high resolution images. */
+void BKE_image_update_gputexture(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser);
+
+ if ((ibuf == NULL) || (w == 0) || (h == 0)) {
+ /* Full reload of texture. */
+ BKE_image_free_gputextures(ima);
+ }
+
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
+ /* Check if we need to update the main gputexture. */
+ if (tex != NULL && tile == ima->tiles.first) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
+ }
+
+ /* Check if we need to update the array gputexture. */
+ tex = ima->gputexture[TEXTARGET_2D_ARRAY][0];
+ if (tex != NULL) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+}
+
+/* these two functions are called on entering and exiting texture paint mode,
+ * temporary disabling/enabling mipmapping on all images for quick texture
+ * updates with glTexSubImage2D. images that didn't change don't have to be
+ * re-uploaded to OpenGL */
+void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
+{
+ LISTBASE_FOREACH (Image *, ima, &bmain->images) {
+ if (BKE_image_has_opengl_texture(ima)) {
+ if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
+ for (int eye = 0; eye < 2; eye++) {
+ for (int a = 0; a < TEXTARGET_COUNT; a++) {
+ if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
+ GPUTexture *tex = ima->gputexture[a][eye];
+ if (tex != NULL) {
+ GPU_texture_mipmap_mode(tex, mipmap, true);
+ }
+ }
+ }
+ }
+ }
+ else {
+ BKE_image_free_gputextures(ima);
+ }
+ }
+ else {
+ ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ }
+ }
+}
+
+/** \} */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 7bf9cb2d0a1..a7fdf93f656 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -517,9 +517,8 @@ static const char *mtex_adrcodes_to_paths(int adrcode, int *UNUSED(array_index))
BLI_snprintf(buf, 128, "%s.%s", base, prop);
return buf;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* Texture types */
@@ -1074,10 +1073,9 @@ static char *get_rna_access(ID *id,
return NULL;
}
- else {
- if (array_index) {
- *array_index = dummy_index;
- }
+
+ if (array_index) {
+ *array_index = dummy_index;
}
/* 'buf' _must_ be initialized in this block */
@@ -1976,7 +1974,7 @@ void do_versions_ipos_to_animato(Main *bmain)
CLOG_WARN(&LOG, "Animation data too new to convert (Version %d)", bmain->versionfile);
return;
}
- else if (G.debug & G_DEBUG) {
+ if (G.debug & G_DEBUG) {
printf("INFO: Converting to Animato...\n");
}
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 4d523ffa2e0..4d073593da7 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -356,9 +356,8 @@ bool object_deform_mball(Object *ob, ListBase *dispbase)
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static BPoint *latt_bp(Lattice *lt, int u, int v, int w)
@@ -575,9 +574,8 @@ struct BPoint *BKE_lattice_active_point_get(Lattice *lt)
if ((lt->actbp != LT_ACTBP_NONE) && (lt->actbp < lt->pntsu * lt->pntsv * lt->pntsw)) {
return &lt->def[lt->actbp];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
void BKE_lattice_center_median(Lattice *lt, float cent[3])
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 64649d84320..cf6139d9449 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -221,7 +221,7 @@ ViewLayer *BKE_view_layer_add(Scene *scene,
view_layer_new = view_layer_add(name);
BLI_addtail(&scene->view_layers, view_layer_new);
- /* Initialise layercollections */
+ /* Initialize layer-collections. */
BKE_layer_collection_sync(scene, view_layer_new);
layer_collection_exclude_all(view_layer_new->layer_collections.first);
@@ -555,21 +555,19 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc)
if (lc->flag & LAYER_COLLECTION_HIDE || lc->collection->flag & COLLECTION_RESTRICT_VIEWPORT) {
return true;
}
- else {
- /* Restriction flags stay set, so we need to check parents */
- CollectionParent *parent = lc->collection->parents.first;
- if (parent) {
- lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
+ /* Restriction flags stay set, so we need to check parents */
+ CollectionParent *parent = lc->collection->parents.first;
- return lc && layer_collection_hidden(view_layer, lc);
- }
- else {
- return false;
- }
+ if (parent) {
+ lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection);
+
+ return lc && layer_collection_hidden(view_layer, lc);
}
return false;
+
+ return false;
}
/**
@@ -1610,10 +1608,9 @@ void BKE_view_layer_selected_editable_objects_iterator_begin(BLI_Iterator *iter,
// First object is valid (selectable and not libdata) -> all good.
return;
}
- else {
- // Object is selectable but not editable -> search for another one.
- BKE_view_layer_selected_editable_objects_iterator_next(iter);
- }
+
+ // Object is selectable but not editable -> search for another one.
+ BKE_view_layer_selected_editable_objects_iterator_next(iter);
}
}
diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c
index a64e550579d..3b7aae98327 100644
--- a/source/blender/blenkernel/intern/lib_id.c
+++ b/source/blender/blenkernel/intern/lib_id.c
@@ -2203,13 +2203,12 @@ char *BKE_id_to_unique_string_key(const struct ID *id)
if (id->lib == NULL) {
return BLI_strdup(id->name);
}
- else {
- /* Prefix with an ascii character in the range of 32..96 (visible)
- * this ensures we can't have a library ID pair that collide.
- * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */
- const char ascii_len = strlen(id->lib->id.name + 2) + 32;
- return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name);
- }
+
+ /* Prefix with an ascii character in the range of 32..96 (visible)
+ * this ensures we can't have a library ID pair that collide.
+ * Where 'LIfooOBbarOBbaz' could be ('LIfoo, OBbarOBbaz') or ('LIfooOBbar', 'OBbaz'). */
+ const char ascii_len = strlen(id->lib->id.name + 2) + 32;
+ return BLI_sprintfN("%c%s%s", ascii_len, id->lib->id.name, id->name);
}
void BKE_id_tag_set_atomic(ID *id, int tag)
@@ -2258,7 +2257,7 @@ static int id_order_compare(const void *a, const void *b)
if (*order_a < *order_b) {
return -1;
}
- else if (*order_a > *order_b) {
+ if (*order_a > *order_b) {
return 1;
}
}
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index 2989c910c45..12d7f0e9e8e 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -117,9 +117,8 @@ void BKE_lib_override_library_copy(ID *dst_id, const ID *src_id, const bool do_f
BKE_lib_override_library_free(&dst_id->override_library, true);
return;
}
- else {
- BKE_lib_override_library_clear(dst_id->override_library, true);
- }
+
+ BKE_lib_override_library_clear(dst_id->override_library, true);
}
else if (src_id->override_library == NULL) {
/* Virtual overrides of embedded data does not require any extra work. */
@@ -1515,7 +1514,7 @@ void BKE_lib_override_library_main_update(Main *bmain)
*/
/** Initialize an override storage. */
-OverrideLibraryStorage *BKE_lib_override_library_operations_store_initialize(void)
+OverrideLibraryStorage *BKE_lib_override_library_operations_store_init(void)
{
return BKE_main_new();
}
diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c
index 00a42b12e07..e687e94073d 100644
--- a/source/blender/blenkernel/intern/lib_query.c
+++ b/source/blender/blenkernel/intern/lib_query.c
@@ -96,9 +96,8 @@ bool BKE_lib_query_foreachid_process(LibraryForeachIDData *data, ID **id_pp, int
}
return true;
}
- else {
- return false;
- }
+
+ return false;
}
int BKE_lib_query_foreachid_process_flags_get(LibraryForeachIDData *data)
@@ -412,6 +411,8 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
return ELEM(id_type_used, ID_MA);
case ID_VO:
return ELEM(id_type_used, ID_MA);
+ case ID_SIM:
+ return ELEM(id_type_used, ID_OB, ID_IM);
case ID_IM:
case ID_VF:
case ID_TXT:
@@ -422,7 +423,6 @@ bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
case ID_PAL:
case ID_PC:
case ID_CF:
- case ID_SIM:
/* Those types never use/reference other IDs... */
return false;
case ID_IP:
diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c
index aa1005c663f..f42df6765c4 100644
--- a/source/blender/blenkernel/intern/light.c
+++ b/source/blender/blenkernel/intern/light.c
@@ -58,7 +58,7 @@ static void light_init_data(ID *id)
MEMCPY_STRUCT_AFTER(la, DNA_struct_default_get(Light), id);
la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
- BKE_curvemapping_initialize(la->curfalloff);
+ BKE_curvemapping_init(la->curfalloff);
}
/**
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 7e859799a4e..444ed0c65b5 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -124,13 +124,11 @@ static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline,
if (spline->flag & MASK_SPLINE_CYCLIC) {
return &points_array[0];
}
- else {
- return NULL;
- }
- }
- else {
- return point + 1;
+
+ return NULL;
}
+
+ return point + 1;
}
static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline,
@@ -141,13 +139,11 @@ static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline,
if (spline->flag & MASK_SPLINE_CYCLIC) {
return &points_array[spline->tot_point - 1];
}
- else {
- return NULL;
- }
- }
- else {
- return point - 1;
+
+ return NULL;
}
+
+ return point - 1;
}
BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline,
@@ -158,13 +154,11 @@ BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline,
if (spline->flag & MASK_SPLINE_CYCLIC) {
return &(points_array[0].bezt);
}
- else {
- return NULL;
- }
- }
- else {
- return &((point + 1))->bezt;
+
+ return NULL;
}
+
+ return &((point + 1))->bezt;
}
MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline)
@@ -703,15 +697,14 @@ float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, c
if (!bezt_next) {
return bezt->weight;
}
- else if (u <= 0.0f) {
+ if (u <= 0.0f) {
return bezt->weight;
}
- else if (u >= 1.0f) {
+ if (u >= 1.0f) {
return bezt_next->weight;
}
- else {
- return mask_point_interp_weight(bezt, bezt_next, u);
- }
+
+ return mask_point_interp_weight(bezt, bezt_next, u);
}
float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u)
@@ -724,53 +717,51 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl
if (!bezt_next) {
return bezt->weight;
}
- else if (u <= 0.0f) {
+ if (u <= 0.0f) {
return bezt->weight;
}
- else if (u >= 1.0f) {
+ if (u >= 1.0f) {
return bezt_next->weight;
}
- else {
- float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */
- int i;
- for (i = 0; i <= point->tot_uw; i++) {
+ float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */
+ int i;
- if (i == 0) {
- cur_u = 0.0f;
- cur_w = 1.0f; /* mask_point_interp_weight will scale it */
- }
- else {
- cur_u = point->uw[i - 1].u;
- cur_w = point->uw[i - 1].w;
- }
+ for (i = 0; i <= point->tot_uw; i++) {
- if (i == point->tot_uw) {
- next_u = 1.0f;
- next_w = 1.0f; /* mask_point_interp_weight will scale it */
- }
- else {
- next_u = point->uw[i].u;
- next_w = point->uw[i].w;
- }
-
- if (u >= cur_u && u <= next_u) {
- break;
- }
+ if (i == 0) {
+ cur_u = 0.0f;
+ cur_w = 1.0f; /* mask_point_interp_weight will scale it */
+ }
+ else {
+ cur_u = point->uw[i - 1].u;
+ cur_w = point->uw[i - 1].w;
}
- fac = (u - cur_u) / (next_u - cur_u);
-
- cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u);
- next_w *= mask_point_interp_weight(bezt, bezt_next, next_u);
-
- if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) {
- return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
+ if (i == point->tot_uw) {
+ next_u = 1.0f;
+ next_w = 1.0f; /* mask_point_interp_weight will scale it */
}
else {
- return (1.0f - fac) * cur_w + fac * next_w;
+ next_u = point->uw[i].u;
+ next_w = point->uw[i].w;
}
+
+ if (u >= cur_u && u <= next_u) {
+ break;
+ }
+ }
+
+ fac = (u - cur_u) / (next_u - cur_u);
+
+ cur_w *= mask_point_interp_weight(bezt, bezt_next, cur_u);
+ next_w *= mask_point_interp_weight(bezt, bezt_next, next_u);
+
+ if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) {
+ return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
}
+
+ return (1.0f - fac) * cur_w + fac * next_w;
}
MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw)
@@ -1521,7 +1512,8 @@ static void mask_layer_shape_from_mask_point(BezTriple *bezt,
fp[7] = bezt->radius;
}
-static void mask_layer_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
+static void mask_layer_shape_to_mask_point(BezTriple *bezt,
+ const float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
{
copy_v2_v2(bezt->vec[0], &fp[0]);
copy_v2_v2(bezt->vec[1], &fp[2]);
@@ -1642,7 +1634,7 @@ MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, const int fr
if (frame == masklay_shape->frame) {
return masklay_shape;
}
- else if (frame < masklay_shape->frame) {
+ if (frame < masklay_shape->frame) {
break;
}
}
@@ -1667,17 +1659,16 @@ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay,
*r_masklay_shape_b = NULL;
return 1;
}
- else if (frame < masklay_shape->frame) {
+ if (frame < masklay_shape->frame) {
if (masklay_shape->prev) {
*r_masklay_shape_a = masklay_shape->prev;
*r_masklay_shape_b = masklay_shape;
return 2;
}
- else {
- *r_masklay_shape_a = masklay_shape;
- *r_masklay_shape_b = NULL;
- return 1;
- }
+
+ *r_masklay_shape_a = masklay_shape;
+ *r_masklay_shape_b = NULL;
+ return 1;
}
}
@@ -1686,12 +1677,11 @@ int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay,
*r_masklay_shape_b = NULL;
return 1;
}
- else {
- *r_masklay_shape_a = NULL;
- *r_masklay_shape_b = NULL;
- return 0;
- }
+ *r_masklay_shape_a = NULL;
+ *r_masklay_shape_b = NULL;
+
+ return 0;
}
MaskLayerShape *BKE_mask_layer_shape_verify_frame(MaskLayer *masklay, const int frame)
@@ -1738,12 +1728,11 @@ static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr,
if (masklay_shape_a->frame < masklay_shape_b->frame) {
return -1;
}
- else if (masklay_shape_a->frame > masklay_shape_b->frame) {
+ if (masklay_shape_a->frame > masklay_shape_b->frame) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
void BKE_mask_layer_shape_sort(MaskLayer *masklay)
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 9b281103a0f..d0f80bf92b9 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -126,9 +126,8 @@ int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const uns
if (spline->flag & MASK_SPLINE_CYCLIC) {
return spline->tot_point * resol;
}
- else {
- return ((spline->tot_point - 1) * resol) + 1;
- }
+
+ return ((spline->tot_point - 1) * resol) + 1;
}
float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index 01d44d070b3..b28cd9c6c8e 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -354,43 +354,38 @@ static bool layer_bucket_isect_test(const MaskRasterLayer *layer,
if (isect_point_tri_v2(cent, v1, v2, v3)) {
return true;
}
- else {
- if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
- (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) ||
- (dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared)) {
- return true;
- }
- else {
- // printf("skip tri\n");
- return false;
- }
- }
- }
- else {
- const float *v1 = cos[face[0]];
- const float *v2 = cos[face[1]];
- const float *v3 = cos[face[2]];
- const float *v4 = cos[face[3]];
- if (isect_point_tri_v2(cent, v1, v2, v3)) {
+ if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
+ (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) ||
+ (dist_squared_to_line_segment_v2(cent, v3, v1) < bucket_max_rad_squared)) {
return true;
}
- else if (isect_point_tri_v2(cent, v1, v3, v4)) {
- return true;
- }
- else {
- if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
- (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) ||
- (dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) ||
- (dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared)) {
- return true;
- }
- else {
- // printf("skip quad\n");
- return false;
- }
- }
+
+ // printf("skip tri\n");
+ return false;
+ }
+
+ const float *v1 = cos[face[0]];
+ const float *v2 = cos[face[1]];
+ const float *v3 = cos[face[2]];
+ const float *v4 = cos[face[3]];
+
+ if (isect_point_tri_v2(cent, v1, v2, v3)) {
+ return true;
+ }
+ if (isect_point_tri_v2(cent, v1, v3, v4)) {
+ return true;
}
+
+ if ((dist_squared_to_line_segment_v2(cent, v1, v2) < bucket_max_rad_squared) ||
+ (dist_squared_to_line_segment_v2(cent, v2, v3) < bucket_max_rad_squared) ||
+ (dist_squared_to_line_segment_v2(cent, v3, v4) < bucket_max_rad_squared) ||
+ (dist_squared_to_line_segment_v2(cent, v4, v1) < bucket_max_rad_squared)) {
+ return true;
+ }
+
+ // printf("skip quad\n");
+ return false;
}
static void layer_bucket_init_dummy(MaskRasterLayer *layer)
@@ -1348,9 +1343,8 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2
}
return best_dist;
}
- else {
- return 1.0f;
- }
+
+ return 1.0f;
}
float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2])
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index b0b542f6000..0520ba3faae 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -268,27 +268,27 @@ Material ***BKE_object_material_array_p(Object *ob)
Mesh *me = ob->data;
return &(me->mat);
}
- else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
+ if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
Curve *cu = ob->data;
return &(cu->mat);
}
- else if (ob->type == OB_MBALL) {
+ if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
return &(mb->mat);
}
- else if (ob->type == OB_GPENCIL) {
+ if (ob->type == OB_GPENCIL) {
bGPdata *gpd = ob->data;
return &(gpd->mat);
}
- else if (ob->type == OB_HAIR) {
+ if (ob->type == OB_HAIR) {
Hair *hair = ob->data;
return &(hair->mat);
}
- else if (ob->type == OB_POINTCLOUD) {
+ if (ob->type == OB_POINTCLOUD) {
PointCloud *pointcloud = ob->data;
return &(pointcloud->mat);
}
- else if (ob->type == OB_VOLUME) {
+ if (ob->type == OB_VOLUME) {
Volume *volume = ob->data;
return &(volume->mat);
}
@@ -301,27 +301,27 @@ short *BKE_object_material_len_p(Object *ob)
Mesh *me = ob->data;
return &(me->totcol);
}
- else if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
+ if (ELEM(ob->type, OB_CURVE, OB_FONT, OB_SURF)) {
Curve *cu = ob->data;
return &(cu->totcol);
}
- else if (ob->type == OB_MBALL) {
+ if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
return &(mb->totcol);
}
- else if (ob->type == OB_GPENCIL) {
+ if (ob->type == OB_GPENCIL) {
bGPdata *gpd = ob->data;
return &(gpd->totcol);
}
- else if (ob->type == OB_HAIR) {
+ if (ob->type == OB_HAIR) {
Hair *hair = ob->data;
return &(hair->totcol);
}
- else if (ob->type == OB_POINTCLOUD) {
+ if (ob->type == OB_POINTCLOUD) {
PointCloud *pointcloud = ob->data;
return &(pointcloud->totcol);
}
- else if (ob->type == OB_VOLUME) {
+ if (ob->type == OB_VOLUME) {
Volume *volume = ob->data;
return &(volume->totcol);
}
@@ -582,7 +582,7 @@ Material **BKE_object_material_get_p(Object *ob, short act)
if (act > ob->totcol) {
return NULL;
}
- else if (act <= 0) {
+ if (act <= 0) {
if (act < 0) {
CLOG_ERROR(&LOG, "Negative material index!");
}
@@ -627,9 +627,8 @@ Material *BKE_gpencil_material(Object *ob, short act)
if (ma != NULL) {
return ma;
}
- else {
- return BKE_material_default_gpencil();
- }
+
+ return BKE_material_default_gpencil();
}
MaterialGPencilStyle *BKE_gpencil_material_settings(Object *ob, short act)
@@ -642,9 +641,8 @@ MaterialGPencilStyle *BKE_gpencil_material_settings(Object *ob, short act)
return ma->gp_style;
}
- else {
- return BKE_material_default_gpencil()->gp_style;
- }
+
+ return BKE_material_default_gpencil()->gp_style;
}
void BKE_object_material_resize(Main *bmain, Object *ob, const short totcol, bool do_id_user)
@@ -959,14 +957,13 @@ void BKE_object_material_array_assign(Main *bmain,
const bool to_object_only)
{
int actcol_orig = ob->actcol;
- short i;
while ((ob->totcol > totcol) && BKE_object_material_slot_remove(bmain, ob)) {
/* pass */
}
/* now we have the right number of slots */
- for (i = 0; i < totcol; i++) {
+ for (int i = 0; i < totcol; i++) {
if (to_object_only && ob->matbits[i] == 0) {
/* If we only assign to object, and that slot uses obdata material, do nothing. */
continue;
@@ -1136,9 +1133,8 @@ static bNode *nodetree_uv_node_recursive(bNode *node)
if (inode->typeinfo->nclass == NODE_CLASS_INPUT && inode->typeinfo->type == SH_NODE_UVMAP) {
return inode;
}
- else {
- return nodetree_uv_node_recursive(inode);
- }
+
+ return nodetree_uv_node_recursive(inode);
}
}
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 94e5f435a43..3a514608c77 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -341,9 +341,8 @@ bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
if (STREQ(basis1name, basis2name)) {
return BKE_mball_is_basis(ob1);
}
- else {
- return false;
- }
+
+ return false;
}
bool BKE_mball_is_any_selected(const MetaBall *mb)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 048af022adb..fccc4380fec 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -591,9 +591,8 @@ bool BKE_mesh_has_custom_loop_normals(Mesh *me)
if (me->edit_mesh) {
return CustomData_has_layer(&me->edit_mesh->bm->ldata, CD_CUSTOMLOOPNORMAL);
}
- else {
- return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
- }
+
+ return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
}
/** Free (or release) any data used by this mesh (does not free the mesh itself). */
@@ -1096,9 +1095,8 @@ Mesh *BKE_mesh_from_object(Object *ob)
if (ob->type == OB_MESH) {
return ob->data;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me)
@@ -1270,12 +1268,11 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v)
if (e->v1 == v) {
return e->v2;
}
- else if (e->v2 == v) {
+ if (e->v2 == v) {
return e->v1;
}
- else {
- return -1;
- }
+
+ return -1;
}
/**
@@ -1406,30 +1403,29 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
if (UNLIKELY(mesh->cd_flag)) {
return;
}
- else {
- MVert *mv;
- MEdge *med;
- int i;
- for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
- if (mv->bweight != 0) {
- mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
- break;
- }
+ MVert *mv;
+ MEdge *med;
+ int i;
+
+ for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
+ if (mv->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ break;
}
+ }
- for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
- if (med->bweight != 0) {
- mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
- if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
- break;
- }
+ for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
+ if (med->bweight != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ break;
}
- if (med->crease != 0) {
- mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
- if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
- break;
- }
+ }
+ if (med->crease != 0) {
+ mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ break;
}
}
}
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 49957b584ad..fe4b8a60796 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -1408,7 +1408,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops,
return false;
}
/* Smooth loop/edge... */
- else if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) {
+ if (BLI_BITMAP_TEST(skip_loops, mlfan_vert_index)) {
if (mlfan_vert_index == ml_curr_index) {
/* We walked around a whole cyclic smooth fan without finding any already-processed loop,
* means we can use initial ml_curr/ml_prev edge as start for this smooth fan. */
@@ -1417,10 +1417,9 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const MLoop *mloops,
/* ... already checked in some previous looping, we can abort. */
return false;
}
- else {
- /* ... we can skip it in future, and keep checking the smooth fan. */
- BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
- }
+
+ /* ... we can skip it in future, and keep checking the smooth fan. */
+ BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
}
}
@@ -2315,22 +2314,21 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
return area_tri_v3(
mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co);
}
- else {
- int i;
- const MLoop *l_iter = loopstart;
- float area;
- float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
-
- /* pack vertex cos into an array for area_poly_v3 */
- for (i = 0; i < mpoly->totloop; i++, l_iter++) {
- copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co);
- }
- /* finally calculate the area */
- area = area_poly_v3((const float(*)[3])vertexcos, (unsigned int)mpoly->totloop);
+ int i;
+ const MLoop *l_iter = loopstart;
+ float area;
+ float(*vertexcos)[3] = BLI_array_alloca(vertexcos, (size_t)mpoly->totloop);
- return area;
+ /* pack vertex cos into an array for area_poly_v3 */
+ for (i = 0; i < mpoly->totloop; i++, l_iter++) {
+ copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co);
}
+
+ /* finally calculate the area */
+ area = area_poly_v3((const float(*)[3])vertexcos, (unsigned int)mpoly->totloop);
+
+ return area;
}
float BKE_mesh_calc_area(const Mesh *me)
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 686f58a0ceb..3572939f78c 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -1047,10 +1047,9 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
}
return false;
}
- else {
- /* Edge is UV boundary if tagged as seam. */
- return (me->flag & ME_SEAM) != 0;
- }
+
+ /* Edge is UV boundary if tagged as seam. */
+ return (me->flag & ME_SEAM) != 0;
}
static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c
index 1b9b8ea6572..ef28e9958fc 100644
--- a/source/blender/blenkernel/intern/mesh_merge.c
+++ b/source/blender/blenkernel/intern/mesh_merge.c
@@ -115,11 +115,10 @@ static int cddm_poly_compare(MLoop *mloop_array,
same_loops = true;
break; /* Polys are identical */
}
- else {
- compare_completed = true;
- same_loops = false;
- break; /* Polys are different */
- }
+
+ compare_completed = true;
+ same_loops = false;
+ break; /* Polys are different */
}
mloop_source++;
@@ -201,9 +200,8 @@ static bool poly_gset_compare_fn(const void *k1, const void *k2)
/* Equality - note that this does not mean equality of polys */
return false;
}
- else {
- return true;
- }
+
+ return true;
}
/**
@@ -412,7 +410,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* In this mode, all vertices merged is enough to dump face */
continue;
}
- else if (merge_mode == MESH_MERGE_VERTS_DUMP_IF_EQUAL) {
+ if (merge_mode == MESH_MERGE_VERTS_DUMP_IF_EQUAL) {
/* Additional condition for face dump: target vertices must make up an identical face */
/* The test has 2 steps: (1) first step is fast ghash lookup, but not failproof */
/* (2) second step is thorough but more costly poly compare */
@@ -578,7 +576,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
BLI_assert(created_edges == 0);
continue;
}
- else if (UNLIKELY(c < 3)) {
+ if (UNLIKELY(c < 3)) {
STACK_DISCARD(oldl, c);
STACK_DISCARD(mloop, c);
if (created_edges > 0) {
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index a4991675d2d..a8937f74dee 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -73,9 +73,8 @@ static bool mesh_remap_bvhtree_query_nearest(BVHTreeFromMesh *treedata,
*r_hit_dist = sqrtf(nearest->dist_sq);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata,
@@ -107,9 +106,8 @@ static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata,
*r_hit_dist = rayhit->dist;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 4d8c0568eb6..338420641cf 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -111,7 +111,7 @@ static int int64_cmp(const void *v1, const void *v2)
if (x1 > x2) {
return 1;
}
- else if (x1 < x2) {
+ if (x1 < x2) {
return -1;
}
@@ -125,28 +125,28 @@ static int search_face_cmp(const void *v1, const void *v2)
if (sfa->es[0].edval > sfb->es[0].edval) {
return 1;
}
- else if (sfa->es[0].edval < sfb->es[0].edval) {
+ if (sfa->es[0].edval < sfb->es[0].edval) {
return -1;
}
- else if (sfa->es[1].edval > sfb->es[1].edval) {
+ if (sfa->es[1].edval > sfb->es[1].edval) {
return 1;
}
- else if (sfa->es[1].edval < sfb->es[1].edval) {
+ if (sfa->es[1].edval < sfb->es[1].edval) {
return -1;
}
- else if (sfa->es[2].edval > sfb->es[2].edval) {
+ if (sfa->es[2].edval > sfb->es[2].edval) {
return 1;
}
- else if (sfa->es[2].edval < sfb->es[2].edval) {
+ if (sfa->es[2].edval < sfb->es[2].edval) {
return -1;
}
- else if (sfa->es[3].edval > sfb->es[3].edval) {
+ if (sfa->es[3].edval > sfb->es[3].edval) {
return 1;
}
- else if (sfa->es[3].edval < sfb->es[3].edval) {
+ if (sfa->es[3].edval < sfb->es[3].edval) {
return -1;
}
@@ -214,6 +214,7 @@ static int search_polyloop_cmp(const void *v1, const void *v2)
*
* \return false if no changes needed to be made.
*/
+/* NOLINTNEXTLINE: readability-function-size */
bool BKE_mesh_validate_arrays(Mesh *mesh,
MVert *mverts,
unsigned int totvert,
@@ -1082,9 +1083,8 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -1161,9 +1161,8 @@ bool BKE_mesh_validate_material_indices(Mesh *me)
DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/** \} */
@@ -1341,13 +1340,13 @@ static int vergedgesort(const void *v1, const void *v2)
if (x1->v1 > x2->v1) {
return 1;
}
- else if (x1->v1 < x2->v1) {
+ if (x1->v1 < x2->v1) {
return -1;
}
- else if (x1->v2 > x2->v2) {
+ if (x1->v2 > x2->v2) {
return 1;
}
- else if (x1->v2 < x2->v2) {
+ if (x1->v2 < x2->v2) {
return -1;
}
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 327e8bfca7a..5789e0f0557 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -112,9 +112,8 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type)
if (type < NUM_MODIFIER_TYPES && modifier_types[type] && modifier_types[type]->name[0] != '\0') {
return modifier_types[type];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/**
@@ -919,11 +918,10 @@ const char *BKE_modifier_path_relbase(Main *bmain, Object *ob)
if (G.relbase_valid || ID_IS_LINKED(ob)) {
return ID_BLEND_PATH(bmain, &ob->id);
}
- else {
- /* last resort, better then using "" which resolves to the current
- * working directory */
- return BKE_tempdir_session();
- }
+
+ /* last resort, better then using "" which resolves to the current
+ * working directory */
+ return BKE_tempdir_session();
}
const char *BKE_modifier_path_relbase_from_global(Object *ob)
@@ -931,11 +929,10 @@ const char *BKE_modifier_path_relbase_from_global(Object *ob)
if (G.relbase_valid || ID_IS_LINKED(ob)) {
return ID_BLEND_PATH_FROM_GLOBAL(&ob->id);
}
- else {
- /* last resort, better then using "" which resolves to the current
- * working directory */
- return BKE_tempdir_session();
- }
+
+ /* last resort, better then using "" which resolves to the current
+ * working directory */
+ return BKE_tempdir_session();
}
/* initializes the path with either */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4a65c6ff5e7..dcac7b01899 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -717,9 +717,8 @@ static bool put_imbuf_cache(
IMB_moviecache_put(clip->cache->moviecache, &key, ibuf);
return true;
}
- else {
- return IMB_moviecache_put_if_possible(clip->cache->moviecache, &key, ibuf);
- }
+
+ return IMB_moviecache_put_if_possible(clip->cache->moviecache, &key, ibuf);
}
static bool moviecache_check_free_proxy(ImBuf *UNUSED(ibuf), void *userkey, void *UNUSED(userdata))
@@ -1866,3 +1865,88 @@ void BKE_movieclip_eval_selection_update(struct Depsgraph *depsgraph, MovieClip
DEG_debug_print_eval(depsgraph, __func__, clip->id.name, clip);
movieclip_selection_sync(clip, (MovieClip *)clip->id.orig_id);
}
+
+/* -------------------------------------------------------------------- */
+/** \name GPU textures
+ * \{ */
+
+static GPUTexture **movieclip_get_gputexture_ptr(MovieClip *clip,
+ MovieClipUser *cuser,
+ eGPUTextureTarget textarget)
+{
+ /* Check if we have an existing entry for that clip user. */
+ MovieClip_RuntimeGPUTexture *tex;
+ for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
+ if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
+ break;
+ }
+ }
+
+ /* If not, allocate a new one. */
+ if (tex == NULL) {
+ tex = (MovieClip_RuntimeGPUTexture *)MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture),
+ __func__);
+
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ tex->gputexture[i] = NULL;
+ }
+
+ memcpy(&tex->user, cuser, sizeof(MovieClipUser));
+ BLI_addtail(&clip->runtime.gputextures, tex);
+ }
+
+ return &tex->gputexture[textarget];
+}
+
+GPUTexture *BKE_movieclip_get_gpu_texture(MovieClip *clip, MovieClipUser *cuser)
+{
+ if (clip == NULL) {
+ return NULL;
+ }
+
+ GPUTexture **tex = movieclip_get_gputexture_ptr(clip, cuser, TEXTARGET_2D);
+ if (*tex) {
+ return *tex;
+ }
+
+ /* check if we have a valid image buffer */
+ ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
+ if (ibuf == NULL) {
+ *tex = GPU_texture_create_error(2, false);
+ return *tex;
+ }
+
+ /* This only means RGBA16F instead of RGBA32F. */
+ const bool high_bitdepth = false;
+ const bool store_premultiplied = ibuf->rect_float ? false : true;
+ *tex = IMB_create_gpu_texture(ibuf, high_bitdepth, store_premultiplied);
+
+ /* Do not generate mips for movieclips... too slow. */
+ GPU_texture_mipmap_mode(*tex, false, true);
+
+ IMB_freeImBuf(ibuf);
+
+ return *tex;
+}
+
+void BKE_movieclip_free_gputexture(struct MovieClip *clip)
+{
+ /* number of gpu textures to keep around as cache
+ * We don't want to keep too many GPU textures for
+ * movie clips around, as they can be large.*/
+ const int MOVIECLIP_NUM_GPUTEXTURES = 1;
+
+ while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
+ MovieClip_RuntimeGPUTexture *tex = (MovieClip_RuntimeGPUTexture *)BLI_pophead(
+ &clip->runtime.gputextures);
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ /* free glsl image binding */
+ if (tex->gputexture[i]) {
+ GPU_texture_free(tex->gputexture[i]);
+ tex->gputexture[i] = NULL;
+ }
+ }
+ MEM_freeN(tex);
+ }
+}
+/** \} */
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 71d49dd1c19..392f95af917 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -241,7 +241,7 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
md->hidden = subd;
}
-static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
+static MDisps *multires_mdisps_init_hidden(Mesh *me, int level)
{
MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
int gridsize = BKE_ccg_gridsize(level);
@@ -407,15 +407,14 @@ int multires_get_level(const Scene *scene,
return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->renderlvl, true) :
mmd->renderlvl;
}
- else if (ob->mode == OB_MODE_SCULPT) {
+ if (ob->mode == OB_MODE_SCULPT) {
return mmd->sculptlvl;
}
- else if (ignore_simplify) {
+ if (ignore_simplify) {
return mmd->lvl;
}
- else {
- return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
- }
+
+ return (scene != NULL) ? get_render_subsurf_level(&scene->r, mmd->lvl, false) : mmd->lvl;
}
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
@@ -553,7 +552,7 @@ static int get_levels_from_disps(Object *ob)
if (md->totdisp == lvl_totdisp) {
break;
}
- else if (md->totdisp < lvl_totdisp) {
+ if (md->totdisp < lvl_totdisp) {
totlvl--;
}
else {
@@ -868,7 +867,7 @@ static void multires_subdivide_legacy(
mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
if (!mdisps) {
- mdisps = multires_mdisps_initialize_hidden(me, totlvl);
+ mdisps = multires_mdisps_init_hidden(me, totlvl);
}
if (mdisps->disps && !updateblock && lvl != 0) {
diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
index 105e56e4219..10a43a4c9b8 100644
--- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c
+++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
@@ -72,7 +72,7 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh
/* Assumes no is normalized; return value's sign is negative if v is on the other side of the
* plane. */
-static float v3_dist_from_plane(float v[3], float center[3], float no[3])
+static float v3_dist_from_plane(const float v[3], const float center[3], const float no[3])
{
float s[3];
sub_v3_v3v3(s, v, center);
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index fa1a53f946e..c9bb9518230 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -111,7 +111,7 @@ static BMVert *unsubdivide_find_any_pole(BMesh *bm, int *elem_id, int elem)
if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole_three(v)) {
return v;
}
- else if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole(v)) {
+ if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole(v)) {
pole = v;
}
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 7012688686b..1ba82b352d1 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -480,46 +480,41 @@ static float nlastrip_get_frame_actionclip(NlaStrip *strip, float cframe, short
if (mode == NLATIME_CONVERT_MAP) {
return strip->end - scale * (cframe - strip->actstart);
}
- else if (mode == NLATIME_CONVERT_UNMAP) {
+ if (mode == NLATIME_CONVERT_UNMAP) {
return (strip->end + (strip->actstart * scale - cframe)) / scale;
}
- else { /* if (mode == NLATIME_CONVERT_EVAL) */
- if (IS_EQF((float)cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
- /* This case prevents the motion snapping back to the first frame at the end of the strip
- * by catching the case where repeats is a whole number, which means that the end of the
- * strip could also be interpreted as the end of the start of a repeat. */
- return strip->actstart;
- }
- else {
- /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
- * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
- */
- return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale;
- }
+ /* if (mode == NLATIME_CONVERT_EVAL) */
+ if (IS_EQF((float)cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
+ /* This case prevents the motion snapping back to the first frame at the end of the strip
+ * by catching the case where repeats is a whole number, which means that the end of the
+ * strip could also be interpreted as the end of the start of a repeat. */
+ return strip->actstart;
}
+
+ /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
+ * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
+ */
+ return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale;
}
- else {
- if (mode == NLATIME_CONVERT_MAP) {
- return strip->start + scale * (cframe - strip->actstart);
- }
- else if (mode == NLATIME_CONVERT_UNMAP) {
- return strip->actstart + (cframe - strip->start) / scale;
- }
- else { /* if (mode == NLATIME_CONVERT_EVAL) */
- if (IS_EQF(cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
- /* This case prevents the motion snapping back to the first frame at the end of the strip
- * by catching the case where repeats is a whole number, which means that the end of the
- * strip could also be interpreted as the end of the start of a repeat. */
- return strip->actend;
- }
- else {
- /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
- * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
- */
- return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale;
- }
- }
+
+ if (mode == NLATIME_CONVERT_MAP) {
+ return strip->start + scale * (cframe - strip->actstart);
+ }
+ if (mode == NLATIME_CONVERT_UNMAP) {
+ return strip->actstart + (cframe - strip->start) / scale;
+ }
+ /* if (mode == NLATIME_CONVERT_EVAL) */
+ if (IS_EQF(cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
+ /* This case prevents the motion snapping back to the first frame at the end of the strip
+ * by catching the case where repeats is a whole number, which means that the end of the
+ * strip could also be interpreted as the end of the start of a repeat. */
+ return strip->actend;
}
+
+ /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
+ * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
+ */
+ return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale;
}
/* non clipped mapping for strip-time <-> global time (for Transitions)
@@ -537,18 +532,15 @@ static float nlastrip_get_frame_transition(NlaStrip *strip, float cframe, short
if (mode == NLATIME_CONVERT_MAP) {
return strip->end - (length * cframe);
}
- else {
- return (strip->end - cframe) / length;
- }
+
+ return (strip->end - cframe) / length;
}
- else {
- if (mode == NLATIME_CONVERT_MAP) {
- return (length * cframe) + strip->start;
- }
- else {
- return (cframe - strip->start) / length;
- }
+
+ if (mode == NLATIME_CONVERT_MAP) {
+ return (length * cframe) + strip->start;
}
+
+ return (cframe - strip->start) / length;
}
/* non clipped mapping for strip-time <-> global time
@@ -882,11 +874,10 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
return true;
}
- else { /* failed... no room before */
- return false;
- }
+ /* failed... no room before */
+ return false;
}
- else if (strip->end > mstrip->end) {
+ if (strip->end > mstrip->end) {
/* check if strip to the right (if it exists) starts before the
* end of the strip we're trying to add
*/
@@ -897,14 +888,12 @@ bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
return true;
}
- else { /* failed... no room after */
- return false;
- }
- }
- else {
- /* just try to add to the meta-strip (no dimension changes needed) */
- return BKE_nlastrips_add_strip(&mstrip->strips, strip);
+ /* failed... no room after */
+ return false;
}
+
+ /* just try to add to the meta-strip (no dimension changes needed) */
+ return BKE_nlastrips_add_strip(&mstrip->strips, strip);
}
/* Adjust the settings of NLA-Strips contained within a Meta-Strip (recursively),
@@ -1034,7 +1023,7 @@ NlaTrack *BKE_nlatrack_find_tweaked(AnimData *adt)
if (BLI_findindex(&nlt->strips, adt->actstrip) != -1) {
return nlt;
}
- else if (G.debug & G_DEBUG) {
+ if (G.debug & G_DEBUG) {
printf("%s: Active strip (%p, %s) not in NLA track found (%p, %s)\n",
__func__,
adt->actstrip,
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 20d65e52b09..d77e7cf862d 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -61,6 +61,7 @@
#include "BKE_lib_query.h"
#include "BKE_main.h"
#include "BKE_node.h"
+#include "BKE_simulation.h"
#include "BLI_ghash.h"
#include "BLI_threads.h"
@@ -845,12 +846,12 @@ static void socket_id_user_increment(bNodeSocket *sock)
switch ((eNodeSocketDatatype)sock->type) {
case SOCK_OBJECT: {
bNodeSocketValueObject *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_IMAGE: {
bNodeSocketValueImage *default_value = sock->default_value;
- id_us_plus(&default_value->value->id);
+ id_us_plus((ID *)default_value->value);
break;
}
case SOCK_FLOAT:
@@ -1265,9 +1266,8 @@ bNode *nodeFindRootParent(bNode *node)
if (node->parent) {
return nodeFindRootParent(node->parent);
}
- else {
- return node->type == NODE_FRAME ? node : NULL;
- }
+
+ return node->type == NODE_FRAME ? node : NULL;
}
/**
@@ -1279,7 +1279,7 @@ bool nodeIsChildOf(const bNode *parent, const bNode *child)
if (parent == child) {
return true;
}
- else if (child->parent) {
+ if (child->parent) {
return nodeIsChildOf(parent, child->parent);
}
return false;
@@ -1338,9 +1338,8 @@ static void iter_backwards_ex(const bNodeTree *ntree,
if (link->fromnode->iter_flag & recursion_mask) {
continue;
}
- else {
- link->fromnode->iter_flag |= recursion_mask;
- }
+
+ link->fromnode->iter_flag |= recursion_mask;
if (!callback(link->fromnode, link->tonode, userdata)) {
return;
@@ -2493,6 +2492,7 @@ ID *BKE_node_tree_find_owner_ID(Main *bmain, struct bNodeTree *ntree)
&bmain->textures,
&bmain->scenes,
&bmain->linestyles,
+ &bmain->simulations,
NULL};
for (int i = 0; lists[i] != NULL; i++) {
@@ -2580,9 +2580,8 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
return ltree;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* sync local composite with real tree */
@@ -2987,9 +2986,8 @@ bNode *nodeGetActiveID(bNodeTree *ntree, short idtype)
return node_get_active_id_recursive(
ntree->active_viewer_key, NODE_INSTANCE_KEY_BASE, ntree, idtype);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
bool nodeSetActiveID(bNodeTree *ntree, short idtype, ID *id)
@@ -3125,9 +3123,8 @@ int nodeSocketLinkLimit(struct bNodeSocket *sock)
int limit = (sock->in_out == SOCK_IN) ? stype->input_link_limit : stype->output_link_limit;
return limit;
}
- else {
- return sock->limit;
- }
+
+ return sock->limit;
}
/* ************** Node Clipboard *********** */
@@ -3417,9 +3414,8 @@ bool BKE_node_instance_hash_tag_key(bNodeInstanceHash *hash, bNodeInstanceKey ke
entry->tag = 1;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash,
@@ -3637,6 +3633,16 @@ void ntreeUpdateAllUsers(Main *main, ID *ngroup)
FOREACH_NODETREE_END;
}
+static void ntreeUpdateSimulationDependencies(Main *main, bNodeTree *simulation_ntree)
+{
+ FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
+ if (GS(owner_id->name) == ID_SIM && ntree == simulation_ntree) {
+ BKE_simulation_update_dependencies((Simulation *)owner_id, main);
+ }
+ }
+ FOREACH_NODETREE_END;
+}
+
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
{
bNode *node;
@@ -3679,7 +3685,6 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntreeInterfaceTypeUpdate(ntree);
}
- /* XXX hack, should be done by depsgraph!! */
if (bmain) {
ntreeUpdateAllUsers(bmain, &ntree->id);
}
@@ -3695,6 +3700,11 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
ntree_validate_links(ntree);
}
+ if (bmain != NULL && ntree->typeinfo == ntreeType_Simulation &&
+ (ntree->id.flag & LIB_EMBEDDED_DATA)) {
+ ntreeUpdateSimulationDependencies(bmain, ntree);
+ }
+
/* clear update flags */
for (node = ntree->nodes.first; node; node = node->next) {
node->update = 0;
@@ -3819,6 +3829,7 @@ static bool node_poll_instance_default(bNode *node, bNodeTree *ntree)
return node->typeinfo->poll(node->typeinfo, ntree);
}
+/* NOLINTNEXTLINE: readability-function-size */
void node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
{
/* Use static type info header to map static int type to identifier string and RNA struct type.
@@ -4336,6 +4347,8 @@ static void registerSimulationNodes(void)
register_node_type_sim_emit_particles();
register_node_type_sim_time();
register_node_type_sim_particle_attribute();
+ register_node_type_sim_age_reached_event();
+ register_node_type_sim_kill_particle();
}
static void registerFunctionNodes(void)
@@ -4346,6 +4359,7 @@ static void registerFunctionNodes(void)
register_node_type_fn_group_instance_id();
register_node_type_fn_combine_strings();
register_node_type_fn_object_transforms();
+ register_node_type_fn_random_float();
}
void init_nodesystem(void)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index ecb2256d080..024e60ea989 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -666,14 +666,14 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type)
if (ob->type == OB_HAIR) {
return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly);
}
- else if (ob->type == OB_POINTCLOUD) {
+ if (ob->type == OB_POINTCLOUD) {
return (mti->modifyPointCloud != NULL) ||
(mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly);
}
- else if (ob->type == OB_VOLUME) {
+ if (ob->type == OB_VOLUME) {
return (mti->modifyVolume != NULL);
}
- else if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) {
return false;
}
@@ -1597,9 +1597,8 @@ bool BKE_object_pose_context_check(const Object *ob)
if ((ob) && (ob->type == OB_ARMATURE) && (ob->pose) && (ob->mode & OB_MODE_POSE)) {
return true;
}
- else {
- return false;
- }
+
+ return false;
}
Object *BKE_object_pose_armature_get(Object *ob)
@@ -2409,7 +2408,7 @@ static bool ob_parcurve(Object *ob, Object *par, float r_mat[4][4])
/* ctime is now a proper var setting of Curve which gets set by Animato like any other var
* that's animated, but this will only work if it actually is animated.
*
- * We divide the curvetime calculated in the previous step by the length of the path,
+ * We divide the curve-time calculated in the previous step by the length of the path,
* to get a time factor, which then gets clamped to lie within 0.0 - 1.0 range.
*/
if (cu->pathlen) {
@@ -3207,9 +3206,8 @@ bool BKE_object_empty_image_frame_is_visible_in_view3d(const Object *ob, const R
if (rv3d->is_persp) {
return (visibility_flag & OB_EMPTY_IMAGE_HIDE_PERSPECTIVE) == 0;
}
- else {
- return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0;
- }
+
+ return (visibility_flag & OB_EMPTY_IMAGE_HIDE_ORTHOGRAPHIC) == 0;
}
bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const RegionView3D *rv3d)
@@ -3269,31 +3267,30 @@ bool BKE_object_minmax_dupli(Depsgraph *depsgraph,
if ((ob->transflag & OB_DUPLI) == 0) {
return ok;
}
- else {
- ListBase *lb;
- DupliObject *dob;
- lb = object_duplilist(depsgraph, scene, ob);
- for (dob = lb->first; dob; dob = dob->next) {
- if ((use_hidden == false) && (dob->no_draw != 0)) {
- /* pass */
- }
- else {
- BoundBox *bb = BKE_object_boundbox_get(dob->ob);
-
- if (bb) {
- int i;
- for (i = 0; i < 8; i++) {
- float vec[3];
- mul_v3_m4v3(vec, dob->mat, bb->vec[i]);
- minmax_v3v3_v3(r_min, r_max, vec);
- }
- ok = true;
+ ListBase *lb;
+ DupliObject *dob;
+ lb = object_duplilist(depsgraph, scene, ob);
+ for (dob = lb->first; dob; dob = dob->next) {
+ if ((use_hidden == false) && (dob->no_draw != 0)) {
+ /* pass */
+ }
+ else {
+ BoundBox *bb = BKE_object_boundbox_get(dob->ob);
+
+ if (bb) {
+ int i;
+ for (i = 0; i < 8; i++) {
+ float vec[3];
+ mul_v3_m4v3(vec, dob->mat, bb->vec[i]);
+ minmax_v3v3_v3(r_min, r_max, vec);
}
+
+ ok = true;
}
}
- free_object_duplilist(lb); /* does restore */
}
+ free_object_duplilist(lb); /* does restore */
return ok;
}
@@ -3636,9 +3633,8 @@ static int pc_cmp(const void *a, const void *b)
if (POINTER_AS_INT(ad->data) > POINTER_AS_INT(bd->data)) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BKE_object_insert_ptcache(Object *ob)
@@ -3917,12 +3913,11 @@ bool BKE_object_flag_test_recursive(const Object *ob, short flag)
if (ob->flag & flag) {
return true;
}
- else if (ob->parent) {
+ if (ob->parent) {
return BKE_object_flag_test_recursive(ob->parent, flag);
}
- else {
- return false;
- }
+
+ return false;
}
bool BKE_object_is_child_recursive(const Object *ob_parent, const Object *ob_child)
@@ -3970,15 +3965,20 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
return flag;
}
-/* Check of objects moves in time. */
-/* NOTE: This function is currently optimized for usage in combination
- * with mti->canDeform, so modifiers can quickly check if their target
- * objects moves (causing deformation motion blur) or not.
+/**
+ * Check of objects moves in time.
+ *
+ * \note This function is currently optimized for usage in combination
+ * with modifier deformation checks (#eModifierTypeType_OnlyDeform),
+ * so modifiers can quickly check if their target objects moves
+ * (causing deformation motion blur) or not.
*
* This makes it possible to give some degree of false-positives here,
* but it's currently an acceptable tradeoff between complexity and check
* speed. In combination with checks of modifier stack and real life usage
- * percentage of false-positives shouldn't be that height.
+ * percentage of false-positives shouldn't be that high.
+ *
+ * \note This function does not consider physics systems.
*/
bool BKE_object_moves_in_time(const Object *object, bool recurse_parent)
{
@@ -4024,15 +4024,15 @@ static bool constructive_modifier_is_deform_modified(ModifierData *md)
(amd->curve_ob != NULL && object_moves_in_time(amd->curve_ob)) ||
(amd->offset_ob != NULL && object_moves_in_time(amd->offset_ob));
}
- else if (md->type == eModifierType_Mirror) {
+ if (md->type == eModifierType_Mirror) {
MirrorModifierData *mmd = (MirrorModifierData *)md;
return mmd->mirror_ob != NULL && object_moves_in_time(mmd->mirror_ob);
}
- else if (md->type == eModifierType_Screw) {
+ if (md->type == eModifierType_Screw) {
ScrewModifierData *smd = (ScrewModifierData *)md;
return smd->ob_axis != NULL && object_moves_in_time(smd->ob_axis);
}
- else if (md->type == eModifierType_MeshSequenceCache) {
+ if (md->type == eModifierType_MeshSequenceCache) {
/* NOTE: Not ideal because it's unknown whether topology changes or not.
* This will be detected later, so by assuming it's only deformation
* going on here we allow to bake deform-only mesh to Alembic and have
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 51ec89cf77d..04f7529c6cd 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -145,7 +145,7 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id)
me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert);
return me->dvert;
}
- else if (GS(id->name) == ID_LT) {
+ if (GS(id->name) == ID_LT) {
Lattice *lt = (Lattice *)id;
lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw,
"lattice deformVert");
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index f498e147110..f485f3d2419 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -37,6 +37,7 @@
#include "DNA_collection_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_pointcloud_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -143,7 +144,10 @@ static void copy_dupli_context(
/* generate a dupli instance
* mat is transform of the object relative to current context (including object obmat)
*/
-static DupliObject *make_dupli(const DupliContext *ctx, Object *ob, float mat[4][4], int index)
+static DupliObject *make_dupli(const DupliContext *ctx,
+ Object *ob,
+ const float mat[4][4],
+ int index)
{
DupliObject *dob;
int i;
@@ -367,17 +371,13 @@ static void vertex_dupli(const VertexDupliData *vdd,
DupliObject *dob;
float obmat[4][4], space_mat[4][4];
- /* obmat is transform to vertex */
- get_duplivert_transform(co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, obmat);
+ /* space_mat is transform to vertex */
+ get_duplivert_transform(
+ co, no, vdd->use_rotation, inst_ob->trackflag, inst_ob->upflag, space_mat);
/* make offset relative to inst_ob using relative child transform */
- mul_mat3_m4_v3((float(*)[4])vdd->child_imat, obmat[3]);
+ mul_mat3_m4_v3((float(*)[4])vdd->child_imat, space_mat[3]);
/* apply obmat _after_ the local vertex transform */
- mul_m4_m4m4(obmat, inst_ob->obmat, obmat);
-
- /* space matrix is constructed by removing obmat transform,
- * this yields the worldspace transform for recursive duplis
- */
- mul_m4_m4m4(space_mat, obmat, inst_ob->imat);
+ mul_m4_m4m4(obmat, inst_ob->obmat, space_mat);
dob = make_dupli(vdd->ctx, vdd->inst_ob, obmat, index);
@@ -523,7 +523,7 @@ static void make_duplis_font(const DupliContext *ctx)
/* Safety check even if it might fail badly when called for original object. */
const bool is_eval_curve = DEG_is_evaluated_id(&cu->id);
- /* advance matching BLI_strncpy_wchar_from_utf8 */
+ /* Advance matching BLI_str_utf8_as_utf32. */
for (a = 0; a < text_len; a++, ct++) {
/* XXX That G.main is *really* ugly, but not sure what to do here...
@@ -573,6 +573,63 @@ static const DupliGenerator gen_dupli_verts_font = {
make_duplis_font /* make_duplis */
};
+/* OB_DUPLIVERTS - PointCloud */
+static void make_child_duplis_pointcloud(const DupliContext *ctx,
+ void *UNUSED(userdata),
+ Object *child)
+{
+ const Object *parent = ctx->object;
+ const PointCloud *pointcloud = parent->data;
+ const float(*co)[3] = pointcloud->co;
+ const float *radius = pointcloud->radius;
+ const float(*rotation)[4] = NULL; /* TODO: add optional rotation attribute. */
+ const float(*orco)[3] = NULL; /* TODO: add optional texture coordinate attribute. */
+
+ /* Relative transform from parent to child space. */
+ float child_imat[4][4];
+ mul_m4_m4m4(child_imat, child->imat, parent->obmat);
+
+ for (int i = 0; i < pointcloud->totpoint; i++) {
+ /* Transform matrix from point position, radius and rotation. */
+ float quat[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ float size[3] = {1.0f, 1.0f, 1.0f};
+ if (radius) {
+ copy_v3_fl(size, radius[i]);
+ }
+ if (rotation) {
+ copy_v4_v4(quat, rotation[i]);
+ }
+
+ float space_mat[4][4];
+ loc_quat_size_to_mat4(space_mat, co[i], quat, size);
+
+ /* Make offset relative to child object using relative child transform,
+ * and apply object matrix after local vertex transform. */
+ mul_mat3_m4_v3(child_imat, space_mat[3]);
+
+ /* Create dupli object. */
+ float obmat[4][4];
+ mul_m4_m4m4(obmat, child->obmat, space_mat);
+ DupliObject *dob = make_dupli(ctx, child, obmat, i);
+ if (orco) {
+ copy_v3_v3(dob->orco, orco[i]);
+ }
+
+ /* Recursion. */
+ make_recursive_duplis(ctx, child, space_mat, i);
+ }
+}
+
+static void make_duplis_pointcloud(const DupliContext *ctx)
+{
+ make_child_duplis(ctx, NULL, make_child_duplis_pointcloud);
+}
+
+static const DupliGenerator gen_dupli_verts_pointcloud = {
+ OB_DUPLIVERTS, /* type */
+ make_duplis_pointcloud /* make_duplis */
+};
+
/* OB_DUPLIFACES */
typedef struct FaceDupliData {
Mesh *me_eval;
@@ -955,13 +1012,12 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem
if (psys_get_particle_state(&sim, a, &state, 0) == 0) {
continue;
}
- else {
- float tquat[4];
- normalize_qt_qt(tquat, state.rot);
- quat_to_mat4(pamat, tquat);
- copy_v3_v3(pamat[3], state.co);
- pamat[3][3] = 1.0f;
- }
+
+ float tquat[4];
+ normalize_qt_qt(tquat, state.rot);
+ quat_to_mat4(pamat, tquat);
+ copy_v3_v3(pamat[3], state.co);
+ pamat[3][3] = 1.0f;
}
if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
@@ -1098,13 +1154,16 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
if (transflag & OB_DUPLIPARTS) {
return &gen_dupli_particles;
}
- else if (transflag & OB_DUPLIVERTS) {
+ if (transflag & OB_DUPLIVERTS) {
if (ctx->object->type == OB_MESH) {
return &gen_dupli_verts;
}
- else if (ctx->object->type == OB_FONT) {
+ if (ctx->object->type == OB_FONT) {
return &gen_dupli_verts_font;
}
+ if (ctx->object->type == OB_POINTCLOUD) {
+ return &gen_dupli_verts_pointcloud;
+ }
}
else if (transflag & OB_DUPLIFACES) {
if (ctx->object->type == OB_MESH) {
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index f94ef946851..ff7cbff06bf 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -753,18 +753,25 @@ struct Ocean *BKE_ocean_add(void)
return oc;
}
-bool BKE_ocean_ensure(struct OceanModifierData *omd)
+bool BKE_ocean_ensure(struct OceanModifierData *omd, const int resolution)
{
if (omd->ocean) {
- return false;
+ /* Check that the ocean has the same resolution than we want now. */
+ if (omd->ocean->_M == resolution * resolution) {
+ return false;
+ }
+
+ BKE_ocean_free(omd->ocean);
}
omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
+ BKE_ocean_init_from_modifier(omd->ocean, omd, resolution);
return true;
}
-void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd)
+void BKE_ocean_init_from_modifier(struct Ocean *ocean,
+ struct OceanModifierData const *omd,
+ const int resolution)
{
short do_heightfield, do_chop, do_normals, do_jacobian;
@@ -774,9 +781,10 @@ void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
BKE_ocean_free_data(ocean);
+
BKE_ocean_init(ocean,
- omd->resolution * omd->resolution,
- omd->resolution * omd->resolution,
+ resolution * resolution,
+ resolution * resolution,
omd->spatial_size,
omd->spatial_size,
omd->wind_velocity,
@@ -1607,7 +1615,8 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o),
}
void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean),
- struct OceanModifierData const *UNUSED(omd))
+ struct OceanModifierData const *UNUSED(omd),
+ int UNUSED(resolution))
{
}
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 2cd5588ccb8..3f3eaae697b 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -415,11 +415,10 @@ enum ePF_FileCompare BKE_packedfile_compare_to_file(const char *ref_file_name,
ret_val = PF_CMP_DIFFERS;
break;
}
- else {
- if (memcmp(buf, ((char *)pf->data) + i, len)) {
- ret_val = PF_CMP_DIFFERS;
- break;
- }
+
+ if (memcmp(buf, ((char *)pf->data) + i, len)) {
+ ret_val = PF_CMP_DIFFERS;
+ break;
}
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 0ba5ec43318..19d5c34ad73 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -426,7 +426,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
if (sima->mode == SI_MODE_PAINT) {
return &ts->imapaint.paint;
}
- else if (sima->mode == SI_MODE_UV) {
+ if (sima->mode == SI_MODE_UV) {
return &ts->uvsculpt->paint;
}
}
@@ -460,7 +460,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
if (sima->mode == SI_MODE_PAINT) {
return PAINT_MODE_TEXTURE_2D;
}
- else if (sima->mode == SI_MODE_UV) {
+ if (sima->mode == SI_MODE_UV) {
return PAINT_MODE_SCULPT_UV;
}
}
@@ -715,7 +715,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2)
if (ps1->h > ps2->h) {
return 1;
}
- else if (ps1->h < ps2->h) {
+ if (ps1->h < ps2->h) {
return -1;
}
@@ -723,7 +723,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2)
if (ps1->s > ps2->s) {
return 1;
}
- else if (ps1->s < ps2->s) {
+ if (ps1->s < ps2->s) {
return -1;
}
@@ -731,7 +731,7 @@ static int palettecolor_compare_hsv(const void *a1, const void *a2)
if (1.0f - ps1->v > 1.0f - ps2->v) {
return 1;
}
- else if (1.0f - ps1->v < 1.0f - ps2->v) {
+ if (1.0f - ps1->v < 1.0f - ps2->v) {
return -1;
}
@@ -747,7 +747,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2)
if (ps1->s > ps2->s) {
return 1;
}
- else if (ps1->s < ps2->s) {
+ if (ps1->s < ps2->s) {
return -1;
}
@@ -755,7 +755,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2)
if (1.0f - ps1->v > 1.0f - ps2->v) {
return 1;
}
- else if (1.0f - ps1->v < 1.0f - ps2->v) {
+ if (1.0f - ps1->v < 1.0f - ps2->v) {
return -1;
}
@@ -763,7 +763,7 @@ static int palettecolor_compare_svh(const void *a1, const void *a2)
if (ps1->h > ps2->h) {
return 1;
}
- else if (ps1->h < ps2->h) {
+ if (ps1->h < ps2->h) {
return -1;
}
@@ -778,7 +778,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2)
if (1.0f - ps1->v > 1.0f - ps2->v) {
return 1;
}
- else if (1.0f - ps1->v < 1.0f - ps2->v) {
+ if (1.0f - ps1->v < 1.0f - ps2->v) {
return -1;
}
@@ -786,7 +786,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2)
if (ps1->h > ps2->h) {
return 1;
}
- else if (ps1->h < ps2->h) {
+ if (ps1->h < ps2->h) {
return -1;
}
@@ -794,7 +794,7 @@ static int palettecolor_compare_vhs(const void *a1, const void *a2)
if (ps1->s > ps2->s) {
return 1;
}
- else if (ps1->s < ps2->s) {
+ if (ps1->s < ps2->s) {
return -1;
}
@@ -811,7 +811,7 @@ static int palettecolor_compare_luminance(const void *a1, const void *a2)
if (lumi1 > lumi2) {
return -1;
}
- else if (lumi1 < lumi2) {
+ if (lumi1 < lumi2) {
return 1;
}
@@ -1424,9 +1424,8 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
if (mmd->sculptlvl > 0) {
return mmd;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
}
@@ -1468,7 +1467,7 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
if (mti->type == eModifierTypeType_OnlyDeform) {
return true;
}
- else if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) {
+ if ((sd->flags & SCULPT_ONLY_DEFORM) == 0) {
return true;
}
}
@@ -1493,6 +1492,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
+ ss->depsgraph = depsgraph;
+
ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob);
ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0;
@@ -1691,7 +1692,6 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object)
CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_DEFAULT, NULL, orig_me->totvert);
BKE_mesh_update_customdata_pointers(orig_me, true);
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY);
- return;
}
void BKE_sculpt_update_object_for_edit(
@@ -2029,8 +2029,7 @@ bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D *v3d)
const bool full_shading = (v3d && (v3d->shading.type > OB_SOLID));
return !(ss->shapekey_active || ss->deform_modifiers_active || full_shading);
}
- else {
- /* Multires and dyntopo always draw directly from the PBVH. */
- return true;
- }
+
+ /* Multires and dyntopo always draw directly from the PBVH. */
+ return true;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index a003daf1042..363706ca969 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -512,9 +512,8 @@ bool psys_check_edited(ParticleSystem *psys)
if (psys->part && psys->part->type == PART_HAIR) {
return (psys->flag & PSYS_EDITED || (psys->edit && psys->edit->edited));
}
- else {
- return (psys->pointcache->edit && psys->pointcache->edit->edited);
- }
+
+ return (psys->pointcache->edit && psys->pointcache->edit->edited);
}
void psys_find_group_weights(ParticleSettings *part)
@@ -1653,12 +1652,11 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
// printf("\tNO CD_ORIGSPACE, assuming not needed\n");
return findex_orig;
}
- else {
- printf("\tNO CD_ORIGSPACE, error out of range\n");
- return DMCACHE_NOTFOUND;
- }
+
+ printf("\tNO CD_ORIGSPACE, error out of range\n");
+ return DMCACHE_NOTFOUND;
}
- else if (findex_orig >= mesh_original->totface) {
+ if (findex_orig >= mesh_original->totface) {
return DMCACHE_NOTFOUND; /* index not in the original mesh */
}
@@ -1919,7 +1917,7 @@ static void psys_particle_on_shape(int UNUSED(distr),
float orco[3])
{
/* TODO */
- float zerovec[3] = {0.0f, 0.0f, 0.0f};
+ const float zerovec[3] = {0.0f, 0.0f, 0.0f};
if (vec) {
copy_v3_v3(vec, zerovec);
}
@@ -2170,10 +2168,10 @@ int do_guides(Depsgraph *depsgraph,
{
ParticleKey key;
- float par_co[3] = {0.0f, 0.0f, 0.0f};
- float par_vel[3] = {0.0f, 0.0f, 0.0f};
- float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
- float orco_offset[3] = {0.0f, 0.0f, 0.0f};
+ const float par_co[3] = {0.0f, 0.0f, 0.0f};
+ const float par_vel[3] = {0.0f, 0.0f, 0.0f};
+ const float par_rot[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ const float orco_offset[3] = {0.0f, 0.0f, 0.0f};
copy_v3_v3(key.co, vec_to_point);
do_kink(&key,
@@ -2555,9 +2553,8 @@ static void psys_thread_create_path(ParticleTask *task,
if (!needupdate) {
return;
}
- else {
- memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
- }
+
+ memset(child_keys, 0, sizeof(*child_keys) * (ctx->segments + 1));
}
/* get parent paths */
@@ -3871,7 +3868,7 @@ void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->clumpcurve = cumap;
}
@@ -3885,7 +3882,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->roughcurve = cumap;
}
@@ -3899,7 +3896,7 @@ void BKE_particlesettings_twist_curve_init(ParticleSettings *part)
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
part->twistcurve = cumap;
}
@@ -4666,10 +4663,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
psys_get_particle_on_path(sim, p, state, 1);
return 1;
}
- else {
- cpa = sim->psys->child + p - totpart;
- pa = sim->psys->particles + cpa->parent;
- }
+
+ cpa = sim->psys->child + p - totpart;
+ pa = sim->psys->particles + cpa->parent;
}
else {
pa = sim->psys->particles + p;
@@ -4691,106 +4687,105 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
psys_get_particle_on_path(sim, p, state, 1);
return 1;
}
- else {
- if (cpa) {
- float mat[4][4];
- ParticleKey *key1;
- float t = (cfra - pa->time) / pa->lifetime;
- float par_orco[3] = {0.0f, 0.0f, 0.0f};
- key1 = &pa->state;
- offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad);
+ if (cpa) {
+ float mat[4][4];
+ ParticleKey *key1;
+ float t = (cfra - pa->time) / pa->lifetime;
+ const float par_orco[3] = {0.0f, 0.0f, 0.0f};
- CLAMP(t, 0.0f, 1.0f);
+ key1 = &pa->state;
+ offset_child(cpa, key1, key1->rot, state, part->childflat, part->childrad);
- unit_m4(mat);
- ParticleChildModifierContext modifier_ctx = {NULL};
- modifier_ctx.thread_ctx = NULL;
- modifier_ctx.sim = sim;
- modifier_ctx.ptex = NULL;
- modifier_ctx.cpa = cpa;
- modifier_ctx.orco = cpa->fuv;
- modifier_ctx.par_co = key1->co;
- modifier_ctx.par_vel = key1->vel;
- modifier_ctx.par_rot = key1->rot;
- modifier_ctx.par_orco = par_orco;
- modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
+ CLAMP(t, 0.0f, 1.0f);
- do_child_modifiers(&modifier_ctx, mat, state, t);
+ unit_m4(mat);
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = NULL;
+ modifier_ctx.sim = sim;
+ modifier_ctx.ptex = NULL;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = cpa->fuv;
+ modifier_ctx.par_co = key1->co;
+ modifier_ctx.par_vel = key1->vel;
+ modifier_ctx.par_rot = key1->rot;
+ modifier_ctx.par_orco = par_orco;
+ modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
- if (psys->lattice_deform_data) {
- BKE_lattice_deform_data_eval_co(
- psys->lattice_deform_data, state->co, psys->lattice_strength);
- }
+ do_child_modifiers(&modifier_ctx, mat, state, t);
+
+ if (psys->lattice_deform_data) {
+ BKE_lattice_deform_data_eval_co(
+ psys->lattice_deform_data, state->co, psys->lattice_strength);
+ }
+ }
+ else {
+ if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
+ copy_particle_key(state, &pa->state, 1);
+ }
+ else if (pa->prev_state.time == cfra) {
+ copy_particle_key(state, &pa->prev_state, 1);
}
else {
- if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
- copy_particle_key(state, &pa->state, 1);
- }
- else if (pa->prev_state.time == cfra) {
- copy_particle_key(state, &pa->prev_state, 1);
- }
- else {
- float dfra, frs_sec = sim->scene->r.frs_sec;
- /* let's interpolate to try to be as accurate as possible */
- if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) {
- if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) {
- /* prev_state is wrong so let's not use it,
- * this can happen at frames 1, 0 or particle birth. */
- dfra = state->time - pa->state.time;
+ float dfra, frs_sec = sim->scene->r.frs_sec;
+ /* let's interpolate to try to be as accurate as possible */
+ if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) {
+ if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) {
+ /* prev_state is wrong so let's not use it,
+ * this can happen at frames 1, 0 or particle birth. */
+ dfra = state->time - pa->state.time;
- copy_particle_key(state, &pa->state, 1);
+ copy_particle_key(state, &pa->state, 1);
- madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
- }
- else {
- ParticleKey keys[4];
- float keytime;
+ madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
+ }
+ else {
+ ParticleKey keys[4];
+ float keytime;
- copy_particle_key(keys + 1, &pa->prev_state, 1);
- copy_particle_key(keys + 2, &pa->state, 1);
+ copy_particle_key(keys + 1, &pa->prev_state, 1);
+ copy_particle_key(keys + 2, &pa->state, 1);
- dfra = keys[2].time - keys[1].time;
+ dfra = keys[2].time - keys[1].time;
- keytime = (state->time - keys[1].time) / dfra;
+ keytime = (state->time - keys[1].time) / dfra;
- /* convert velocity to timestep size */
- mul_v3_fl(keys[1].vel, dfra * timestep);
- mul_v3_fl(keys[2].vel, dfra * timestep);
+ /* convert velocity to timestep size */
+ mul_v3_fl(keys[1].vel, dfra * timestep);
+ mul_v3_fl(keys[2].vel, dfra * timestep);
- psys_interpolate_particle(-1, keys, keytime, state, 1);
+ psys_interpolate_particle(-1, keys, keytime, state, 1);
- /* convert back to real velocity */
- mul_v3_fl(state->vel, 1.f / (dfra * timestep));
+ /* convert back to real velocity */
+ mul_v3_fl(state->vel, 1.f / (dfra * timestep));
- interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime);
- interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime);
- }
+ interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime);
+ interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime);
}
- else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) {
- /* linear interpolation using only pa->state */
+ }
+ else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) {
+ /* linear interpolation using only pa->state */
- dfra = state->time - pa->state.time;
+ dfra = state->time - pa->state.time;
- copy_particle_key(state, &pa->state, 1);
+ copy_particle_key(state, &pa->state, 1);
- madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
- }
- else {
- /* Extrapolating over big ranges is not accurate
- * so let's just give something close to reasonable back. */
- copy_particle_key(state, &pa->state, 0);
- }
+ madd_v3_v3v3fl(state->co, state->co, state->vel, dfra / frs_sec);
}
-
- if (sim->psys->lattice_deform_data) {
- BKE_lattice_deform_data_eval_co(
- sim->psys->lattice_deform_data, state->co, psys->lattice_strength);
+ else {
+ /* Extrapolating over big ranges is not accurate
+ * so let's just give something close to reasonable back. */
+ copy_particle_key(state, &pa->state, 0);
}
}
- return 1;
+ if (sim->psys->lattice_deform_data) {
+ BKE_lattice_deform_data_eval_co(
+ sim->psys->lattice_deform_data, state->co, psys->lattice_strength);
+ }
}
+
+ return 1;
}
void psys_get_dupli_texture(ParticleSystem *psys,
@@ -4844,9 +4839,8 @@ void psys_get_dupli_texture(ParticleSystem *psys,
orco);
return;
}
- else {
- pa = psys->particles + cpa->pa[0];
- }
+
+ pa = psys->particles + cpa->pa[0];
}
if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) {
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index dcd2a0b8fae..da5fdc85561 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -305,10 +305,9 @@ static bool check_path_length(int k,
/* something over the maximum step value */
return false;
}
- else {
- *cur_length += step_length;
- return true;
- }
+
+ *cur_length += step_length;
+ return true;
}
void psys_apply_child_modifiers(ParticleThreadContext *ctx,
@@ -685,7 +684,7 @@ static void do_rough(const float loc[3],
}
static void do_rough_end(
- const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
+ const float loc[3], const float mat[4][4], float t, float fac, float shape, ParticleKey *state)
{
float rough[2];
float roughfac;
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index e0dccd4d14a..dc6d5e974ed 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -829,22 +829,20 @@ static int distribute_compare_orig_index(const void *p1, const void *p2, void *u
if (index1 < index2) {
return -1;
}
- else if (index1 == index2) {
+ if (index1 == index2) {
/* this pointer comparison appears to make qsort stable for glibc,
* and apparently on solaris too, makes the renders reproducible */
if (p1 < p2) {
return -1;
}
- else if (p1 == p2) {
+ if (p1 == p2) {
return 0;
}
- else {
- return 1;
- }
- }
- else {
+
return 1;
}
+
+ return 1;
}
static void distribute_invalid(ParticleSimulationData *sim, int from)
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index bec9cbbad79..7bfc0ca764f 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -106,9 +106,8 @@ static int particles_are_dynamic(ParticleSystem *psys)
if (psys->part->type == PART_HAIR) {
return psys->flag & PSYS_HAIR_DYNAMICS;
}
- else {
- return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID);
- }
+
+ return ELEM(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID);
}
float psys_get_current_display_percentage(ParticleSystem *psys, const bool use_render_params)
@@ -131,12 +130,11 @@ static int tot_particles(ParticleSystem *psys, PTCacheID *pid)
if (pid && psys->pointcache->flag & PTCACHE_EXTERNAL) {
return pid->cache->totpoint;
}
- else if (psys->part->distr == PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
+ if (psys->part->distr == PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
return psys->part->grid_res * psys->part->grid_res * psys->part->grid_res - psys->totunexist;
}
- else {
- return psys->part->totpart - psys->totunexist;
- }
+
+ return psys->part->totpart - psys->totunexist;
}
void psys_reset(ParticleSystem *psys, int mode)
@@ -570,7 +568,7 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
}
}
-static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
+static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
@@ -595,7 +593,7 @@ static void initialize_particle_texture(ParticleSimulationData *sim, ParticleDat
}
/* set particle parameters that don't change during particle's life */
-void initialize_particle(ParticleSimulationData *sim, ParticleData *pa)
+void init_particle(ParticleSimulationData *sim, ParticleData *pa)
{
ParticleSettings *part = sim->psys->part;
float birth_time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -629,7 +627,7 @@ static void initialize_all_particles(ParticleSimulationData *sim)
LOOP_PARTICLES
{
if (!(emit_from_volume_grid && (pa->flag & PARS_UNEXIST) != 0)) {
- initialize_particle(sim, pa);
+ init_particle(sim, pa);
}
}
}
@@ -1092,7 +1090,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
* We could only do it now because we'll need to know coordinate
* before sampling the texture.
*/
- initialize_particle_texture(sim, pa, p);
+ init_particle_texture(sim, pa, p);
if (part->phystype == PART_PHYS_BOIDS && pa->boid) {
BoidParticle *bpa = pa->boid;
@@ -1709,13 +1707,12 @@ static void sph_evaluate_func(BVHTree *tree,
BLI_bvhtree_range_query(tree, co, interaction_radius, callback, pfr);
break;
}
- else {
- BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
- BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+ BLI_rw_mutex_lock(&psys_bvhtree_rwlock, THREAD_LOCK_READ);
- BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
- }
+ BLI_bvhtree_range_query(psys[i]->bvhtree, co, interaction_radius, callback, pfr);
+
+ BLI_rw_mutex_unlock(&psys_bvhtree_rwlock);
}
}
static void sph_density_accum_cb(void *userdata, int index, const float co[3], float squared_dist)
@@ -2612,9 +2609,8 @@ static float collision_newton_rhapson(ParticleCollision *col,
d1 = 0.f;
continue;
}
- else {
- return -1.f;
- }
+
+ return -1.f;
}
dd = (t1 - t0) / (d1 - d0);
@@ -2634,7 +2630,7 @@ static float collision_newton_rhapson(ParticleCollision *col,
d1 = 0.f;
continue;
}
- else if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) {
+ if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) {
return -1.f;
}
@@ -2648,9 +2644,8 @@ static float collision_newton_rhapson(ParticleCollision *col,
return t1;
}
- else {
- return -1.f;
- }
+
+ return -1.f;
}
}
return -1.0;
@@ -2927,164 +2922,163 @@ static int collision_response(ParticleSimulationData *sim,
return 0;
}
/* figure out velocity and other data after collision */
- else {
- /* velocity directly before collision to be modified into velocity directly after collision */
- float v0[3];
- /* normal component of v0 */
- float v0_nor[3];
- /* tangential component of v0 */
- float v0_tan[3];
- /* tangential component of collision surface velocity */
- float vc_tan[3];
- float v0_dot, vc_dot;
- float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_rng_get_float(rng) - 0.5f);
- float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_rng_get_float(rng) - 0.5f);
- float distance, nor[3], dot;
-
- CLAMP(damp, 0.0f, 1.0f);
- CLAMP(frict, 0.0f, 1.0f);
-
- /* get exact velocity right before collision */
- madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1);
-
- /* Convert collider velocity from `1/frame_step` to `1/s` TODO:
- * here we assume 1 frame step for collision modifier. */
- mul_v3_fl(pce->vel, col->inv_timestep);
-
- /* calculate tangential particle velocity */
- v0_dot = dot_v3v3(pce->nor, v0);
- madd_v3_v3v3fl(v0_tan, v0, pce->nor, -v0_dot);
-
- /* calculate tangential collider velocity */
- vc_dot = dot_v3v3(pce->nor, pce->vel);
- madd_v3_v3v3fl(vc_tan, pce->vel, pce->nor, -vc_dot);
-
- /* handle friction effects (tangential and angular velocity) */
- if (frict > 0.0f) {
- /* angular <-> linear velocity */
- if (dynamic_rotation) {
- float vr_tan[3], v1_tan[3], ave[3];
-
- /* linear velocity of particle surface */
- cross_v3_v3v3(vr_tan, pce->nor, pa->state.ave);
- mul_v3_fl(vr_tan, pa->size);
-
- /* change to coordinates that move with the collision plane */
- sub_v3_v3v3(v1_tan, v0_tan, vc_tan);
-
- /* The resulting velocity is a weighted average of particle cm & surface
- * velocity. This weight (related to particle's moment of inertia) could
- * be made a parameter for angular <-> linear conversion.
- */
- madd_v3_v3fl(v1_tan, vr_tan, -0.4);
- mul_v3_fl(v1_tan, 1.0f / 1.4f); /* 1/(1+0.4) */
- /* rolling friction is around 0.01 of sliding friction
- * (could be made a parameter) */
- mul_v3_fl(v1_tan, 1.0f - 0.01f * frict);
-
- /* surface_velocity is opposite to cm velocity */
- negate_v3_v3(vr_tan, v1_tan);
-
- /* get back to global coordinates */
- add_v3_v3(v1_tan, vc_tan);
-
- /* convert to angular velocity*/
- cross_v3_v3v3(ave, vr_tan, pce->nor);
- mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f));
-
- /* only friction will cause change in linear & angular velocity */
- interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict);
- interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict);
- }
- else {
- /* just basic friction (unphysical due to the friction model used in Blender) */
- interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict);
- }
+ /* velocity directly before collision to be modified into velocity directly after collision */
+ float v0[3];
+ /* normal component of v0 */
+ float v0_nor[3];
+ /* tangential component of v0 */
+ float v0_tan[3];
+ /* tangential component of collision surface velocity */
+ float vc_tan[3];
+ float v0_dot, vc_dot;
+ float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_rng_get_float(rng) - 0.5f);
+ float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_rng_get_float(rng) - 0.5f);
+ float distance, nor[3], dot;
+
+ CLAMP(damp, 0.0f, 1.0f);
+ CLAMP(frict, 0.0f, 1.0f);
+
+ /* get exact velocity right before collision */
+ madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1);
+
+ /* Convert collider velocity from `1/frame_step` to `1/s` TODO:
+ * here we assume 1 frame step for collision modifier. */
+ mul_v3_fl(pce->vel, col->inv_timestep);
+
+ /* calculate tangential particle velocity */
+ v0_dot = dot_v3v3(pce->nor, v0);
+ madd_v3_v3v3fl(v0_tan, v0, pce->nor, -v0_dot);
+
+ /* calculate tangential collider velocity */
+ vc_dot = dot_v3v3(pce->nor, pce->vel);
+ madd_v3_v3v3fl(vc_tan, pce->vel, pce->nor, -vc_dot);
+
+ /* handle friction effects (tangential and angular velocity) */
+ if (frict > 0.0f) {
+ /* angular <-> linear velocity */
+ if (dynamic_rotation) {
+ float vr_tan[3], v1_tan[3], ave[3];
+
+ /* linear velocity of particle surface */
+ cross_v3_v3v3(vr_tan, pce->nor, pa->state.ave);
+ mul_v3_fl(vr_tan, pa->size);
+
+ /* change to coordinates that move with the collision plane */
+ sub_v3_v3v3(v1_tan, v0_tan, vc_tan);
+
+ /* The resulting velocity is a weighted average of particle cm & surface
+ * velocity. This weight (related to particle's moment of inertia) could
+ * be made a parameter for angular <-> linear conversion.
+ */
+ madd_v3_v3fl(v1_tan, vr_tan, -0.4);
+ mul_v3_fl(v1_tan, 1.0f / 1.4f); /* 1/(1+0.4) */
+
+ /* rolling friction is around 0.01 of sliding friction
+ * (could be made a parameter) */
+ mul_v3_fl(v1_tan, 1.0f - 0.01f * frict);
+
+ /* surface_velocity is opposite to cm velocity */
+ negate_v3_v3(vr_tan, v1_tan);
+
+ /* get back to global coordinates */
+ add_v3_v3(v1_tan, vc_tan);
+
+ /* convert to angular velocity*/
+ cross_v3_v3v3(ave, vr_tan, pce->nor);
+ mul_v3_fl(ave, 1.0f / MAX2(pa->size, 0.001f));
+
+ /* only friction will cause change in linear & angular velocity */
+ interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict);
+ interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict);
}
+ else {
+ /* just basic friction (unphysical due to the friction model used in Blender) */
+ interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict);
+ }
+ }
- /* Stickiness was possibly added before,
- * so cancel that before calculating new normal velocity.
- * Otherwise particles go flying out of the surface
- * because of high reversed sticky velocity. */
- if (v0_dot < 0.0f) {
- v0_dot += pd->pdef_stickness;
- if (v0_dot > 0.0f) {
- v0_dot = 0.0f;
- }
+ /* Stickiness was possibly added before,
+ * so cancel that before calculating new normal velocity.
+ * Otherwise particles go flying out of the surface
+ * because of high reversed sticky velocity. */
+ if (v0_dot < 0.0f) {
+ v0_dot += pd->pdef_stickness;
+ if (v0_dot > 0.0f) {
+ v0_dot = 0.0f;
}
+ }
- /* damping and flipping of velocity around normal */
- v0_dot *= 1.0f - damp;
- vc_dot *= through ? damp : 1.0f;
+ /* damping and flipping of velocity around normal */
+ v0_dot *= 1.0f - damp;
+ vc_dot *= through ? damp : 1.0f;
- /* calculate normal particle velocity */
- /* special case for object hitting the particle from behind */
- if (through == 0 && ((vc_dot > 0.0f && v0_dot > 0.0f && vc_dot > v0_dot) ||
- (vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) {
- mul_v3_v3fl(v0_nor, pce->nor, vc_dot);
- }
- else if (v0_dot > 0.f) {
- mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot);
- }
- else {
- mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot);
- }
+ /* calculate normal particle velocity */
+ /* special case for object hitting the particle from behind */
+ if (through == 0 && ((vc_dot > 0.0f && v0_dot > 0.0f && vc_dot > v0_dot) ||
+ (vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) {
+ mul_v3_v3fl(v0_nor, pce->nor, vc_dot);
+ }
+ else if (v0_dot > 0.f) {
+ mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot);
+ }
+ else {
+ mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot);
+ }
- /* combine components together again */
- add_v3_v3v3(v0, v0_nor, v0_tan);
+ /* combine components together again */
+ add_v3_v3v3(v0, v0_nor, v0_tan);
- if (col->boid) {
- /* keep boids above ground */
- BoidParticle *bpa = pa->boid;
- if (bpa->data.mode == eBoidMode_OnLand || co[2] <= col->boid_z) {
- co[2] = col->boid_z;
- v0[2] = 0.0f;
- }
+ if (col->boid) {
+ /* keep boids above ground */
+ BoidParticle *bpa = pa->boid;
+ if (bpa->data.mode == eBoidMode_OnLand || co[2] <= col->boid_z) {
+ co[2] = col->boid_z;
+ v0[2] = 0.0f;
}
+ }
- /* re-apply acceleration to final location and velocity */
- madd_v3_v3v3fl(pa->state.co, co, v0, dt2);
- madd_v3_v3fl(pa->state.co, col->acc, 0.5f * dt2 * dt2);
- madd_v3_v3v3fl(pa->state.vel, v0, col->acc, dt2);
+ /* re-apply acceleration to final location and velocity */
+ madd_v3_v3v3fl(pa->state.co, co, v0, dt2);
+ madd_v3_v3fl(pa->state.co, col->acc, 0.5f * dt2 * dt2);
+ madd_v3_v3v3fl(pa->state.vel, v0, col->acc, dt2);
- /* make sure particle stays on the right side of the surface */
- if (!through) {
- distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor);
+ /* make sure particle stays on the right side of the surface */
+ if (!through) {
+ distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor);
- if (distance < col->radius + COLLISION_MIN_DISTANCE) {
- madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
- }
+ if (distance < col->radius + COLLISION_MIN_DISTANCE) {
+ madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
+ }
- dot = dot_v3v3(nor, v0);
- if (dot < 0.f) {
- madd_v3_v3fl(v0, nor, -dot);
- }
+ dot = dot_v3v3(nor, v0);
+ if (dot < 0.f) {
+ madd_v3_v3fl(v0, nor, -dot);
+ }
- distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor);
+ distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor);
- if (distance < col->radius + COLLISION_MIN_DISTANCE) {
- madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
- }
+ if (distance < col->radius + COLLISION_MIN_DISTANCE) {
+ madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
+ }
- dot = dot_v3v3(nor, pa->state.vel);
- if (dot < 0.f) {
- madd_v3_v3fl(pa->state.vel, nor, -dot);
- }
+ dot = dot_v3v3(nor, pa->state.vel);
+ if (dot < 0.f) {
+ madd_v3_v3fl(pa->state.vel, nor, -dot);
}
+ }
- /* add stickiness to surface */
- madd_v3_v3fl(pa->state.vel, pce->nor, -pd->pdef_stickness);
+ /* add stickiness to surface */
+ madd_v3_v3fl(pa->state.vel, pce->nor, -pd->pdef_stickness);
- /* set coordinates for next iteration */
- copy_v3_v3(col->co1, co);
- copy_v3_v3(col->co2, pa->state.co);
+ /* set coordinates for next iteration */
+ copy_v3_v3(col->co1, co);
+ copy_v3_v3(col->co2, pa->state.co);
- copy_v3_v3(col->ve1, v0);
- copy_v3_v3(col->ve2, pa->state.vel);
+ copy_v3_v3(col->ve1, v0);
+ copy_v3_v3(col->ve2, pa->state.vel);
- col->f = f;
- }
+ col->f = f;
/* if permeability random roll succeeded, disable collider for this sim step */
if (through) {
@@ -3676,12 +3670,11 @@ static float sync_timestep(ParticleSystem *psys, float t_frac)
if (t_frac == 1.0f) {
return psys->dt_frac;
}
- else if (t_frac + (psys->dt_frac * TIMESTEP_EXPANSION_TOLERANCE) >= 1.0f) {
+ if (t_frac + (psys->dt_frac * TIMESTEP_EXPANSION_TOLERANCE) >= 1.0f) {
return 1.0f - t_frac;
}
- else {
- return psys->dt_frac;
- }
+
+ return psys->dt_frac;
}
/************************************************/
@@ -4372,7 +4365,7 @@ static void particles_fluid_step(ParticleSimulationData *sim,
max_size = MAX3(size[0] / (float)upres, size[1] / (float)upres, size[2] / (float)upres);
/* Set particle position. */
- float posParticle[3] = {posX, posY, posZ};
+ const float posParticle[3] = {posX, posY, posZ};
copy_v3_v3(pa->state.co, posParticle);
/* Normalize to unit cube around 0. */
@@ -4405,7 +4398,7 @@ static void particles_fluid_step(ParticleSimulationData *sim,
pa->state.co[0], pa->state.co[1], pa->state.co[2]);
# endif
/* Set particle velocity. */
- float velParticle[3] = {velX, velY, velZ};
+ const float velParticle[3] = {velX, velY, velZ};
copy_v3_v3(pa->state.vel, velParticle);
mul_v3_fl(pa->state.vel, fds->dx);
# if 0
@@ -4537,11 +4530,11 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
return;
}
/* Cache is supposed to be baked, but no data was found so bail out */
- else if (cache->flag & PTCACHE_BAKED) {
+ if (cache->flag & PTCACHE_BAKED) {
psys_reset(psys, PSYS_RESET_CACHE_MISS);
return;
}
- else if (cache_result == PTCACHE_READ_OLD) {
+ if (cache_result == PTCACHE_READ_OLD) {
psys->cfra = (float)cache->simframe;
cached_step(sim, psys->cfra, use_render_params);
}
@@ -4584,7 +4577,7 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_
psys->dt_frac = get_base_time_step(part);
}
else if ((int)cfra == startframe) {
- /* Variable time step; initialise to subframes */
+ /* Variable time step; initialize to sub-frames. */
psys->dt_frac = get_base_time_step(part);
}
else if (psys->dt_frac < MIN_TIMESTEP) {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 92a47f24240..1dd22a0a28d 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -109,18 +109,15 @@ int BB_widest_axis(const BB *bb)
if (dim[0] > dim[2]) {
return 0;
}
- else {
- return 2;
- }
+
+ return 2;
}
- else {
- if (dim[1] > dim[2]) {
- return 1;
- }
- else {
- return 2;
- }
+
+ if (dim[1] > dim[2]) {
+ return 1;
}
+
+ return 2;
}
void BBC_update_centroid(BBC *bbc)
@@ -275,9 +272,8 @@ static int map_insert_vert(
*value_p = POINTER_FROM_INT(value_i);
return value_i;
}
- else {
- return POINTER_AS_INT(*value_p);
- }
+
+ return POINTER_AS_INT(*value_p);
}
/* Find vertices used by the faces in this node and update the draw buffers */
@@ -804,14 +800,13 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
/* immediately hit leaf node */
return node;
}
- else {
- /* come back later when children are done */
- pbvh_stack_push(iter, node, true);
- /* push two child nodes on the stack */
- pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
- pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
- }
+ /* come back later when children are done */
+ pbvh_stack_push(iter, node, true);
+
+ /* push two child nodes on the stack */
+ pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
+ pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
}
return NULL;
@@ -838,10 +833,9 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
/* immediately hit leaf node */
return node;
}
- else {
- pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
- pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
- }
+
+ pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset + 1, false);
+ pbvh_stack_push(iter, iter->pbvh->nodes + node->children_offset, false);
}
return NULL;
@@ -1391,16 +1385,15 @@ static int pbvh_flush_bb(PBVH *pbvh, PBVHNode *node, int flag)
return update;
}
- else {
- update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag);
- update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag);
- if (update & PBVH_UpdateBB) {
- update_node_vb(pbvh, node);
- }
- if (update & PBVH_UpdateOriginalBB) {
- node->orig_vb = node->vb;
- }
+ update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset, flag);
+ update |= pbvh_flush_bb(pbvh, pbvh->nodes + node->children_offset + 1, flag);
+
+ if (update & PBVH_UpdateBB) {
+ update_node_vb(pbvh, node);
+ }
+ if (update & PBVH_UpdateOriginalBB) {
+ node->orig_vb = node->vb;
}
return update;
@@ -1667,9 +1660,8 @@ bool BKE_pbvh_has_faces(const PBVH *pbvh)
if (pbvh->type == PBVH_BMESH) {
return (pbvh->bm->totface != 0);
}
- else {
- return (pbvh->totprim != 0);
- }
+
+ return (pbvh->totprim != 0);
}
void BKE_pbvh_bounding_box(const PBVH *pbvh, float min[3], float max[3])
@@ -2029,9 +2021,8 @@ bool ray_face_intersection_quad(const float ray_start[3],
*depth = depth_test;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool ray_face_intersection_tri(const float ray_start[3],
@@ -2047,9 +2038,8 @@ bool ray_face_intersection_tri(const float ray_start[3],
*depth = depth_test;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/* Take advantage of the fact we know this wont be an intersection.
@@ -2100,9 +2090,8 @@ bool ray_face_nearest_quad(const float ray_start[3],
}
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool ray_face_nearest_tri(const float ray_start[3],
@@ -2122,9 +2111,8 @@ bool ray_face_nearest_tri(const float ray_start[3],
*depth = depth_test;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool pbvh_faces_node_raycast(PBVH *pbvh,
@@ -2357,7 +2345,7 @@ void BKE_pbvh_raycast_project_ray_root(
struct IsectRayAABB_Precalc ray;
float ray_normal_inv[3];
float offset = 1.0f + 1e-3f;
- float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
+ const float offset_vec[3] = {1e-3f, 1e-3f, 1e-3f};
if (original) {
BKE_pbvh_node_get_original_BB(pbvh->nodes, bb_min_root, bb_max_root);
@@ -2617,7 +2605,7 @@ static PlaneAABBIsect test_frustum_aabb(const float bb_min[3],
if (dot_v3v3(planes[i], vmin) + planes[i][3] < 0) {
return ISECT_OUTSIDE;
}
- else if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) {
+ if (dot_v3v3(planes[i], vmax) + planes[i][3] <= 0) {
ret = ISECT_INTERSECT;
}
}
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index e87c7c8d46d..a04fa1506d0 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -184,14 +184,13 @@ static BMVert *bm_vert_hash_lookup_chain(GHash *deleted_verts, BMVert *v)
/* not remapped*/
return v;
}
- else if (*v_next_p == NULL) {
+ if (*v_next_p == NULL) {
/* removed and not remapped */
return NULL;
}
- else {
- /* remapped */
- v = *v_next_p;
- }
+
+ /* remapped */
+ v = *v_next_p;
}
}
@@ -1738,9 +1737,8 @@ static void pbvh_bmesh_node_limit_ensure_fast(
candidate = i_iter;
break;
}
- else {
- num_child2++;
- }
+
+ num_child2++;
}
if (candidate != -1) {
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 4b09f7542c7..ae18f3289e4 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1404,9 +1404,8 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra))
if (!surface->data) {
return 0;
}
- else {
- return surface->data->total_points;
- }
+
+ return surface->data->total_points;
}
static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message))
@@ -1511,7 +1510,7 @@ static int ptcache_rigidbody_write(int index, void *rb_v, void **data, int UNUSE
if (ob && ob->rigidbody_object) {
RigidBodyOb *rbo = ob->rigidbody_object;
- if (rbo->type == RBO_TYPE_ACTIVE) {
+ if (rbo->type == RBO_TYPE_ACTIVE && rbo->shared->physics_object != NULL) {
#ifdef WITH_BULLET
RB_body_get_position(rbo->shared->physics_object, rbo->pos);
RB_body_get_orientation(rbo->shared->physics_object, rbo->orn);
@@ -2128,7 +2127,7 @@ static int ptcache_path(PTCacheID *pid, char *filename)
return BLI_path_slash_ensure(filename); /* new strlen() */
}
- else if (G.relbase_valid || lib) {
+ if (G.relbase_valid || lib) {
char file[MAX_PTCACHE_PATH]; /* we don't want the dir, only the file */
BLI_split_file_part(blendfilename, file, sizeof(file));
@@ -2521,9 +2520,8 @@ int BKE_ptcache_mem_index_find(PTCacheMem *pm, unsigned int index)
return -1;
}
- else {
- return (index < pm->totpoint ? index : -1);
- }
+
+ return (index < pm->totpoint ? index : -1);
}
void BKE_ptcache_mem_pointers_init(PTCacheMem *pm)
@@ -2627,10 +2625,10 @@ static int ptcache_old_elemsize(PTCacheID *pid)
if (pid->type == PTCACHE_TYPE_SOFTBODY) {
return 6 * sizeof(float);
}
- else if (pid->type == PTCACHE_TYPE_PARTICLES) {
+ if (pid->type == PTCACHE_TYPE_PARTICLES) {
return sizeof(ParticleKey);
}
- else if (pid->type == PTCACHE_TYPE_CLOTH) {
+ if (pid->type == PTCACHE_TYPE_CLOTH) {
return 9 * sizeof(float);
}
@@ -3585,16 +3583,15 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
return BLI_exists(filename);
}
- else {
- PTCacheMem *pm = pid->cache->mem_cache.first;
- for (; pm; pm = pm->next) {
- if (pm->frame == cfra) {
- return 1;
- }
+ PTCacheMem *pm = pid->cache->mem_cache.first;
+
+ for (; pm; pm = pm->next) {
+ if (pm->frame == cfra) {
+ return 1;
}
- return 0;
}
+ return 0;
}
void BKE_ptcache_id_time(
PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale)
diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c
index df5d93beccb..21889acba3c 100644
--- a/source/blender/blenkernel/intern/pointcloud.c
+++ b/source/blender/blenkernel/intern/pointcloud.c
@@ -169,8 +169,8 @@ BoundBox *BKE_pointcloud_boundbox_get(Object *ob)
for (int a = 0; a < pointcloud->totpoint; a++) {
float *co = pointcloud_co[a];
float radius = (pointcloud_radius) ? pointcloud_radius[a] : 0.0f;
- float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
- float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
+ const float co_min[3] = {co[0] - radius, co[1] - radius, co[2] - radius};
+ const float co_max[3] = {co[0] + radius, co[1] + radius, co[2] + radius};
DO_MIN(co_min, min);
DO_MAX(co_max, max);
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 4752782eaeb..ece7d0f9136 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -466,10 +466,10 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return shape;
}
-/* Create new physics sim collision shape for object and store it,
- * or remove the existing one first and replace...
+/* Helper function to create physics collision shape for object.
+ * Returns a new collision shape.
*/
-static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
+static rbCollisionShape *rigidbody_validate_sim_shape_helper(RigidBodyWorld *rbw, Object *ob)
{
RigidBodyOb *rbo = ob->rigidbody_object;
rbCollisionShape *new_shape = NULL;
@@ -484,12 +484,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
/* sanity check */
if (rbo == NULL) {
- return;
- }
-
- /* don't create a new shape if we already have one and don't want to rebuild it */
- if (rbo->shared->physics_shape && !rebuild) {
- return;
+ return NULL;
}
/* if automatically determining dimensions, use the Object's boundbox
@@ -539,7 +534,7 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
break;
case RB_SHAPE_CONVEXH:
- /* try to emged collision margin */
+ /* try to embed collision margin */
has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume) {
@@ -555,18 +550,69 @@ static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
case RB_SHAPE_TRIMESH:
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
break;
+ case RB_SHAPE_COMPOUND:
+ new_shape = RB_shape_new_compound();
+ rbCollisionShape *childShape = NULL;
+ float loc[3], rot[4];
+ float mat[4][4];
+ /* Add children to the compound shape */
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, childObject) {
+ if (childObject->parent == ob) {
+ childShape = rigidbody_validate_sim_shape_helper(rbw, childObject);
+ if (childShape) {
+ BKE_object_matrix_local_get(childObject, mat);
+ mat4_to_loc_quat(loc, rot, mat);
+ RB_compound_add_child_shape(new_shape, childShape, loc, rot);
+ }
+ }
+ }
+ FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
+
+ break;
}
- /* use box shape if we can't fall back to old shape */
- if (new_shape == NULL && rbo->shared->physics_shape == NULL) {
+ /* use box shape if it failed to create new shape */
+ if (new_shape == NULL) {
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
}
+ if (new_shape) {
+ RB_shape_set_margin(new_shape, RBO_GET_MARGIN(rbo));
+ }
+
+ return new_shape;
+}
+
+/* Create new physics sim collision shape for object and store it,
+ * or remove the existing one first and replace...
+ */
+static void rigidbody_validate_sim_shape(RigidBodyWorld *rbw, Object *ob, bool rebuild)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ rbCollisionShape *new_shape = NULL;
+
+ /* sanity check */
+ if (rbo == NULL) {
+ return;
+ }
+
+ /* don't create a new shape if we already have one and don't want to rebuild it */
+ if (rbo->shared->physics_shape && !rebuild) {
+ return;
+ }
+
+ /* Also don't create a shape if this object is parent of a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
+ }
+
+ new_shape = rigidbody_validate_sim_shape_helper(rbw, ob);
+
/* assign new collision shape if creation was successful */
if (new_shape) {
if (rbo->shared->physics_shape) {
RB_shape_delete(rbo->shared->physics_shape);
}
rbo->shared->physics_shape = new_shape;
- RB_shape_set_margin(rbo->shared->physics_shape, RBO_GET_MARGIN(rbo));
}
}
@@ -750,7 +796,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects,
* but it's needed for constraints to update correctly. */
if (rbo->shared->physics_shape == NULL || rebuild) {
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
}
if (rbo->shared->physics_object) {
@@ -760,6 +806,12 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
/* remove rigid body if it already exists before creating a new one */
if (rbo->shared->physics_object) {
RB_body_delete(rbo->shared->physics_object);
+ rbo->shared->physics_object = NULL;
+ }
+ /* Don't create rigid body object if the parent is a compound shape */
+ if (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ return;
}
mat4_to_loc_quat(loc, rot, ob->obmat);
@@ -793,7 +845,7 @@ static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
}
- if (rbw && rbw->shared->physics_world) {
+ if (rbw && rbw->shared->physics_world && rbo->shared->physics_object) {
RB_dworld_add_body(rbw->shared->physics_world, rbo->shared->physics_object, rbo->col_groups);
}
}
@@ -1179,9 +1231,12 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
* - object must exist
* - cannot add rigid body if it already exists
*/
- if (ob == NULL || (ob->rigidbody_object != NULL)) {
+ if (ob == NULL) {
return NULL;
}
+ if (ob->rigidbody_object != NULL) {
+ return ob->rigidbody_object;
+ }
/* create new settings data, and link it up */
rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
@@ -1530,7 +1585,11 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -1541,8 +1600,12 @@ static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
int i = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
- rbw->objects[i] = object;
- i++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ rbw->objects[i] = object;
+ i++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
}
@@ -1754,11 +1817,13 @@ static void rigidbody_update_simulation(Depsgraph *depsgraph,
/* refresh shape... */
if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
/* mesh/shape data changed, so force shape refresh */
- rigidbody_validate_sim_shape(ob, true);
+ rigidbody_validate_sim_shape(rbw, ob, true);
/* now tell RB sim about it */
/* XXX: we assume that this can only get applied for active/passive shapes
* that will be included as rigidbodies. */
- RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ if (rbo->shared->physics_object != NULL && rbo->shared->physics_shape != NULL) {
+ RB_body_set_collision_shape(rbo->shared->physics_object, rbo->shared->physics_shape);
+ }
}
}
rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
@@ -1817,7 +1882,8 @@ static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBod
Base *base = BKE_view_layer_base_find(view_layer, ob);
RigidBodyOb *rbo = ob->rigidbody_object;
/* Reset kinematic state for transformed objects. */
- if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
+ if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ) &&
+ rbo->shared->physics_object) {
RB_body_set_kinematic_state(rbo->shared->physics_object,
rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
RB_body_set_mass(rbo->shared->physics_object, RBO_GET_MASS(rbo));
@@ -1840,8 +1906,13 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
{
RigidBodyOb *rbo = ob->rigidbody_object;
+ /* True if the shape of this object's parent is of type compound */
+ bool obCompoundParent = (ob->parent != NULL && ob->parent->rigidbody_object != NULL &&
+ ob->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND);
+
/* keep original transform for kinematic and passive objects */
- if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) {
+ if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE ||
+ obCompoundParent) {
return;
}
@@ -1963,7 +2034,11 @@ void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime
int n = 0;
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (rbw->group, object) {
(void)object;
- n++;
+ /* Ignore if this object is the direct child of an object with a compound shape */
+ if (object->parent == NULL || object->parent->rigidbody_object == NULL ||
+ object->parent->rigidbody_object->shape != RB_SHAPE_COMPOUND) {
+ n++;
+ }
}
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
@@ -2000,7 +2075,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
return;
}
/* make sure we don't go out of cache frame range */
- else if (ctime > endframe) {
+ if (ctime > endframe) {
ctime = endframe;
}
@@ -2008,7 +2083,7 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime
if (rbw->shared->physics_world == NULL && !(cache->flag & PTCACHE_BAKED)) {
return;
}
- else if (rbw->objects == NULL) {
+ if (rbw->objects == NULL) {
rigidbody_update_ob_array(rbw);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 5ae2f4b9005..bdda03bab12 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -127,7 +127,7 @@ static void scene_init_data(ID *id)
mblur_shutter_curve = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(mblur_shutter_curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(mblur_shutter_curve);
+ BKE_curvemapping_init(mblur_shutter_curve);
BKE_curvemap_reset(mblur_shutter_curve->cm,
&mblur_shutter_curve->clipr,
CURVE_PRESET_MAX,
@@ -140,13 +140,13 @@ static void scene_init_data(ID *id)
/* grease pencil multiframe falloff curve */
scene->toolsettings->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = scene->toolsettings->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(
gp_falloff_curve->cm, &gp_falloff_curve->clipr, CURVE_PRESET_GAUSS, CURVEMAP_SLOPE_POSITIVE);
scene->toolsettings->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_primitive_curve = scene->toolsettings->gp_sculpt.cur_primitive;
- BKE_curvemapping_initialize(gp_primitive_curve);
+ BKE_curvemapping_init(gp_primitive_curve);
BKE_curvemap_reset(gp_primitive_curve->cm,
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
@@ -839,83 +839,78 @@ Scene *BKE_scene_duplicate(Main *bmain, Scene *sce, eSceneCopyMethod type)
return sce_copy;
}
- else {
- eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
- BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy);
- id_us_min(&sce_copy->id);
- id_us_ensure_real(&sce_copy->id);
+ eDupli_ID_Flags duplicate_flags = U.dupflag | USER_DUP_OBJECT;
- BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
+ BKE_id_copy(bmain, (ID *)sce, (ID **)&sce_copy);
+ id_us_min(&sce_copy->id);
+ id_us_ensure_real(&sce_copy->id);
- /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
+ BKE_animdata_duplicate_id_action(bmain, &sce_copy->id, duplicate_flags);
- if (type == SCE_COPY_FULL) {
- /* Scene duplication is always root of duplication currently. */
- const bool is_subprocess = false;
+ /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks. */
- if (!is_subprocess) {
- BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
- BKE_main_id_clear_newpoins(bmain);
- /* In case root duplicated ID is linked, assume we want to get a local copy of it and
- * duplicate all expected linked data. */
- if (ID_IS_LINKED(sce)) {
- duplicate_flags |= USER_DUP_LINKED_ID;
- }
+ if (type == SCE_COPY_FULL) {
+ /* Scene duplication is always root of duplication currently. */
+ const bool is_subprocess = false;
+
+ if (!is_subprocess) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
+ /* In case root duplicated ID is linked, assume we want to get a local copy of it and
+ * duplicate all expected linked data. */
+ if (ID_IS_LINKED(sce)) {
+ duplicate_flags |= USER_DUP_LINKED_ID;
}
+ }
- /* Copy Freestyle LineStyle datablocks. */
- LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
- LISTBASE_FOREACH (
- FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
- BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags);
- }
+ /* Copy Freestyle LineStyle datablocks. */
+ LISTBASE_FOREACH (ViewLayer *, view_layer_dst, &sce_copy->view_layers) {
+ LISTBASE_FOREACH (FreestyleLineSet *, lineset, &view_layer_dst->freestyle_config.linesets) {
+ BKE_id_copy_for_duplicate(bmain, (ID *)lineset->linestyle, duplicate_flags);
}
+ }
- /* Full copy of world (included animations) */
- BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags);
+ /* Full copy of world (included animations) */
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->world, duplicate_flags);
- /* Full copy of GreasePencil. */
- BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags);
+ /* Full copy of GreasePencil. */
+ BKE_id_copy_for_duplicate(bmain, (ID *)sce->gpd, duplicate_flags);
- /* Deep-duplicate collections and objects (using preferences' settings for which sub-data to
- * duplicate along the object itself). */
- BKE_collection_duplicate(bmain,
- NULL,
- sce_copy->master_collection,
- duplicate_flags,
- LIB_ID_DUPLICATE_IS_SUBPROCESS);
+ /* 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);
- if (!is_subprocess) {
- /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
- BKE_libblock_relink_to_newid(&sce_copy->id);
+ if (!is_subprocess) {
+ /* This code will follow into all ID links using an ID tagged with LIB_TAG_NEW.*/
+ BKE_libblock_relink_to_newid(&sce_copy->id);
#ifndef NDEBUG
- /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
- * flags. */
- ID *id_iter;
- FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
- BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0);
- }
- FOREACH_MAIN_ID_END;
+ /* Call to `BKE_libblock_relink_to_newid` above is supposed to have cleared all those
+ * flags. */
+ ID *id_iter;
+ FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
+ BLI_assert((id_iter->tag & LIB_TAG_NEW) == 0);
+ }
+ FOREACH_MAIN_ID_END;
#endif
- /* Cleanup. */
- BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
- BKE_main_id_clear_newpoins(bmain);
+ /* Cleanup. */
+ BKE_main_id_tag_all(bmain, LIB_TAG_NEW, false);
+ BKE_main_id_clear_newpoins(bmain);
- BKE_main_collection_sync(bmain);
- }
+ BKE_main_collection_sync(bmain);
}
- else {
- /* Remove sequencer if not full copy */
- /* XXX Why in Hell? :/ */
- remove_sequencer_fcurves(sce_copy);
- BKE_sequencer_editing_free(sce_copy, true);
- }
-
- return sce_copy;
}
+ else {
+ /* Remove sequencer if not full copy */
+ /* XXX Why in Hell? :/ */
+ remove_sequencer_fcurves(sce_copy);
+ BKE_sequencer_editing_free(sce_copy, true);
+ }
+
+ return sce_copy;
}
void BKE_scene_groups_relink(Scene *sce)
@@ -1642,7 +1637,7 @@ bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
if (act == -1) {
return false;
}
- else if (scene->r.views.first == scene->r.views.last) {
+ if (scene->r.views.first == scene->r.views.last) {
/* ensure 1 view is kept */
return false;
}
@@ -1663,13 +1658,11 @@ int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
if (for_render) {
return min_ii(r->simplify_subsurf_render, lvl);
}
- else {
- return min_ii(r->simplify_subsurf, lvl);
- }
- }
- else {
- return lvl;
+
+ return min_ii(r->simplify_subsurf, lvl);
}
+
+ return lvl;
}
int get_render_child_particle_number(const RenderData *r, int num, bool for_render)
@@ -1678,13 +1671,11 @@ int get_render_child_particle_number(const RenderData *r, int num, bool for_rend
if (for_render) {
return (int)(r->simplify_particles_render * num);
}
- else {
- return (int)(r->simplify_particles * num);
- }
- }
- else {
- return num;
+
+ return (int)(r->simplify_particles * num);
}
+
+ return num;
}
/**
@@ -1699,7 +1690,7 @@ Base *_setlooper_base_step(Scene **sce_iter, ViewLayer *view_layer, Base *base)
/* Common case, step to the next. */
return base->next;
}
- else if ((base == NULL) && (view_layer != NULL)) {
+ if ((base == NULL) && (view_layer != NULL)) {
/* 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) {
@@ -2018,9 +2009,8 @@ const char *BKE_scene_multiview_render_view_name_get(const RenderData *rd, const
if (srv) {
return srv->name;
}
- else {
- return "";
- }
+
+ return "";
}
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
@@ -2041,9 +2031,8 @@ int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
if (STREQ(viewname, srv->name)) {
return nr;
}
- else {
- nr += 1;
- }
+
+ nr += 1;
}
}
@@ -2094,9 +2083,8 @@ const char *BKE_scene_multiview_view_suffix_get(const RenderData *rd, const char
if (srv) {
return srv->suffix;
}
- else {
- return viewname;
- }
+
+ return viewname;
}
const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const int view_id)
@@ -2104,10 +2092,9 @@ const char *BKE_scene_multiview_view_id_suffix_get(const RenderData *rd, const i
if ((rd->scemode & R_MULTIVIEW) == 0) {
return "";
}
- else {
- const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id);
- return BKE_scene_multiview_view_suffix_get(rd, viewname);
- }
+
+ const char *viewname = BKE_scene_multiview_render_view_name_get(rd, view_id);
+ return BKE_scene_multiview_view_suffix_get(rd, viewname);
}
void BKE_scene_multiview_view_prefix_get(Scene *scene,
@@ -2175,10 +2162,9 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd)
if (rd->im_format.views_format == R_IMF_VIEWS_STEREO_3D) {
return 1;
}
- else {
- /* R_IMF_VIEWS_INDIVIDUAL */
- return BKE_scene_multiview_num_views_get(rd);
- }
+
+ /* R_IMF_VIEWS_INDIVIDUAL */
+ return BKE_scene_multiview_num_views_get(rd);
}
/* Manipulation of depsgraph storage. */
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 5c2d5b0087f..be35c7b161b 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -483,10 +483,9 @@ static size_t deflate_imbuf_to_file(ImBuf *ibuf,
return BLI_gzip_mem_to_file_at_pos(
ibuf->rect, header_entry->size_raw, file, header_entry->offset, level);
}
- else {
- return BLI_gzip_mem_to_file_at_pos(
- ibuf->rect_float, header_entry->size_raw, file, header_entry->offset, level);
- }
+
+ return BLI_gzip_mem_to_file_at_pos(
+ ibuf->rect_float, header_entry->size_raw, file, header_entry->offset, level);
}
static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntry *header_entry)
@@ -495,10 +494,9 @@ static size_t inflate_file_to_imbuf(ImBuf *ibuf, FILE *file, DiskCacheHeaderEntr
return BLI_ungzip_file_to_mem_at_pos(
ibuf->rect, header_entry->size_raw, file, header_entry->offset);
}
- else {
- return BLI_ungzip_file_to_mem_at_pos(
- ibuf->rect_float, header_entry->size_raw, file, header_entry->offset);
- }
+
+ return BLI_ungzip_file_to_mem_at_pos(
+ ibuf->rect_float, header_entry->size_raw, file, header_entry->offset);
}
static void seq_disk_cache_read_header(FILE *file, DiskCacheHeader *header)
@@ -1304,11 +1302,10 @@ bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context,
BKE_sequencer_cache_put(context, seq, cfra, type, ibuf, cost, skip_disk_cache);
return true;
}
- else {
- seq_cache_set_temp_cache_linked(scene, scene->ed->cache->last_key);
- scene->ed->cache->last_key = NULL;
- return false;
- }
+
+ seq_cache_set_temp_cache_linked(scene, scene->ed->cache->last_key);
+ scene->ed->cache->last_key = NULL;
+ return false;
}
void BKE_sequencer_cache_put(const SeqRenderData *context,
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 4a2ad88bb28..55de375ce1e 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -3269,9 +3269,8 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context,
if (input == 0) { /* Current frame. */
return floor(seq->start + s->frameMap[nr]);
}
- else { /* Next frame. */
- return ceil(seq->start + s->frameMap[nr]);
- }
+ /* Next frame. */
+ return ceil(seq->start + s->frameMap[nr]);
}
static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, Sequence *seq, float cfra)
@@ -4024,7 +4023,7 @@ static int early_out_fade(Sequence *UNUSED(seq), float facf0, float facf1)
if (facf0 == 0.0f && facf1 == 0.0f) {
return EARLY_USE_INPUT_1;
}
- else if (facf0 == 1.0f && facf1 == 1.0f) {
+ if (facf0 == 1.0f && facf1 == 1.0f) {
return EARLY_USE_INPUT_2;
}
return EARLY_DO_EFFECT;
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index a630170d6d5..a38fe252731 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -393,10 +393,10 @@ static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *m
{
CurvesModifierData *cmd = (CurvesModifierData *)smd;
- float black[3] = {0.0f, 0.0f, 0.0f};
- float white[3] = {1.0f, 1.0f, 1.0f};
+ const float black[3] = {0.0f, 0.0f, 0.0f};
+ const float white[3] = {1.0f, 1.0f, 1.0f};
- BKE_curvemapping_initialize(&cmd->curve_mapping);
+ BKE_curvemapping_init(&cmd->curve_mapping);
BKE_curvemapping_premultiply(&cmd->curve_mapping, 0);
BKE_curvemapping_set_black_white(&cmd->curve_mapping, black, white);
@@ -525,7 +525,7 @@ static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImB
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
- BKE_curvemapping_initialize(&hcmd->curve_mapping);
+ BKE_curvemapping_init(&hcmd->curve_mapping);
modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 5481cfe8193..6cdebcab904 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1356,9 +1356,8 @@ const char *BKE_sequence_give_name(Sequence *seq)
if (!(seq->type & SEQ_TYPE_EFFECT)) {
return seq->strip->dir;
}
- else {
- return "Effect";
- }
+
+ return "Effect";
}
return name;
}
@@ -1662,13 +1661,12 @@ static int seq_num_files(Scene *scene, char views_format, const bool is_multivie
if (!is_multiview) {
return 1;
}
- else if (views_format == R_IMF_VIEWS_STEREO_3D) {
+ if (views_format == R_IMF_VIEWS_STEREO_3D) {
return 1;
}
/* R_IMF_VIEWS_INDIVIDUAL */
- else {
- return BKE_scene_multiview_num_views_get(&scene->r);
- }
+
+ return BKE_scene_multiview_num_views_get(&scene->r);
}
static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir)
@@ -1959,9 +1957,8 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
return ibuf;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
static void seq_proxy_build_frame(const SeqRenderData *context,
@@ -2056,9 +2053,8 @@ static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, con
if (BLI_access(str, R_OK) == 0) {
return false;
}
- else {
- return view_id != 0;
- }
+
+ return view_id != 0;
}
return false;
}
@@ -2426,7 +2422,7 @@ static void color_balance_byte_float(StripColorBalance *cb_,
while (p < e) {
if (m) {
- float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
+ const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f};
p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]];
p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]];
@@ -3351,35 +3347,34 @@ static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr
if (!mask) {
return NULL;
}
- else {
- AnimData *adt;
- Mask *mask_temp;
- MaskRasterHandle *mr_handle;
- mask_temp = BKE_mask_copy_nolib(mask);
+ AnimData *adt;
+ Mask *mask_temp;
+ MaskRasterHandle *mr_handle;
- BKE_mask_evaluate(mask_temp, mask->sfra + nr, true);
+ mask_temp = BKE_mask_copy_nolib(mask);
- /* anim-data */
- adt = BKE_animdata_from_id(&mask->id);
- const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
- context->depsgraph, mask->sfra + nr);
- BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
+ BKE_mask_evaluate(mask_temp, mask->sfra + nr, true);
- maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
+ /* anim-data */
+ adt = BKE_animdata_from_id(&mask->id);
+ const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(
+ context->depsgraph, mask->sfra + nr);
+ BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false);
- mr_handle = BKE_maskrasterize_handle_new();
+ maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__);
- BKE_maskrasterize_handle_init(
- mr_handle, mask_temp, context->rectx, context->recty, true, true, true);
+ mr_handle = BKE_maskrasterize_handle_new();
- BKE_mask_free(mask_temp);
- MEM_freeN(mask_temp);
+ BKE_maskrasterize_handle_init(
+ mr_handle, mask_temp, context->rectx, context->recty, true, true, true);
- BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf);
+ BKE_mask_free(mask_temp);
+ MEM_freeN(mask_temp);
- BKE_maskrasterize_handle_free(mr_handle);
- }
+ BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf);
+
+ BKE_maskrasterize_handle_free(mr_handle);
if (make_float) {
/* pixels */
@@ -3823,9 +3818,8 @@ static float seq_estimate_render_cost_end(Scene *scene, clock_t begin)
if (time_max != 0) {
return time_spent / time_max;
}
- else {
- return 1;
- }
+
+ return 1;
}
static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context,
@@ -3926,7 +3920,7 @@ static int seq_get_early_out_for_blend_mode(Sequence *seq)
if (early_out == EARLY_USE_INPUT_2) {
return EARLY_USE_INPUT_1;
}
- else if (early_out == EARLY_USE_INPUT_1) {
+ if (early_out == EARLY_USE_INPUT_1) {
return EARLY_USE_INPUT_2;
}
}
@@ -4429,9 +4423,8 @@ int BKE_sequence_tx_get_final_left(Sequence *seq, bool metaclip)
return max_ii(BKE_sequence_tx_get_final_left(seq, false),
BKE_sequence_tx_get_final_left((Sequence *)seq->tmp, true));
}
- else {
- return (seq->start - seq->startstill) + seq->startofs;
- }
+
+ return (seq->start - seq->startstill) + seq->startofs;
}
int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip)
{
@@ -4440,9 +4433,8 @@ int BKE_sequence_tx_get_final_right(Sequence *seq, bool metaclip)
return min_ii(BKE_sequence_tx_get_final_right(seq, false),
BKE_sequence_tx_get_final_right((Sequence *)seq->tmp, true));
}
- else {
- return ((seq->start + seq->len) + seq->endstill) - seq->endofs;
- }
+
+ return ((seq->start + seq->len) + seq->endstill) - seq->endofs;
}
void BKE_sequence_tx_set_final_left(Sequence *seq, int val)
@@ -4734,9 +4726,8 @@ bool BKE_sequence_base_shuffle_ex(ListBase *seqbasep,
BKE_sequence_calc(evil_scene, test);
return false;
}
- else {
- return true;
- }
+
+ return true;
}
bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
@@ -4981,7 +4972,7 @@ ListBase *BKE_sequence_seqbase(ListBase *seqbase, Sequence *seq)
if (seq == iseq) {
return seqbase;
}
- else if (iseq->seqbase.first && (lb = BKE_sequence_seqbase(&iseq->seqbase, seq))) {
+ if (iseq->seqbase.first && (lb = BKE_sequence_seqbase(&iseq->seqbase, seq))) {
return lb;
}
}
@@ -4999,7 +4990,7 @@ Sequence *BKE_sequence_metastrip(ListBase *seqbase, Sequence *meta, Sequence *se
if (seq == iseq) {
return meta;
}
- else if (iseq->seqbase.first && (rval = BKE_sequence_metastrip(&iseq->seqbase, iseq, seq))) {
+ if (iseq->seqbase.first && (rval = BKE_sequence_metastrip(&iseq->seqbase, iseq, seq))) {
return rval;
}
}
@@ -5184,8 +5175,8 @@ Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, bool rec
if (STREQ(name, iseq->name + 2)) {
return iseq;
}
- else if (recursive && (iseq->seqbase.first) &&
- (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) {
+ if (recursive && (iseq->seqbase.first) &&
+ (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) {
return rseq;
}
}
@@ -5207,7 +5198,7 @@ Sequence *BKE_sequencer_from_elem(ListBase *seqbase, StripElem *se)
(ARRAY_HAS_ITEM(se, iseq->strip->stripdata, iseq->len))) {
break;
}
- else if ((seq_found = BKE_sequencer_from_elem(&iseq->seqbase, se))) {
+ if ((seq_found = BKE_sequencer_from_elem(&iseq->seqbase, se))) {
iseq = seq_found;
break;
}
@@ -5247,24 +5238,22 @@ int BKE_sequencer_active_get_pair(Scene *scene, Sequence **seq_act, Sequence **s
if (*seq_act == NULL) {
return 0;
}
- else {
- Sequence *seq;
- *seq_other = NULL;
+ Sequence *seq;
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT && (seq != (*seq_act))) {
- if (*seq_other) {
- return 0;
- }
- else {
- *seq_other = seq;
- }
+ *seq_other = NULL;
+
+ for (seq = ed->seqbasep->first; seq; seq = seq->next) {
+ if (seq->flag & SELECT && (seq != (*seq_act))) {
+ if (*seq_other) {
+ return 0;
}
- }
- return (*seq_other != NULL);
+ *seq_other = seq;
+ }
}
+
+ return (*seq_other != NULL);
}
Mask *BKE_sequencer_mask_get(Scene *scene)
@@ -5274,9 +5263,8 @@ Mask *BKE_sequencer_mask_get(Scene *scene)
if (seq_act && seq_act->type == SEQ_TYPE_MASK) {
return seq_act->mask;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/* api like funcs for adding */
@@ -6082,6 +6070,64 @@ bool BKE_sequencer_render_loop_check(Sequence *seq_main, Sequence *seq)
return false;
}
+static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ LISTBASE_FOREACH (Sequence *, user_seq, seqbase) {
+ /* Look in metas for usage of seq. */
+ if (user_seq->type == SEQ_TYPE_META) {
+ sequencer_flag_users_for_removal(scene, &user_seq->seqbase, seq);
+ }
+
+ /* Clear seq from modifiers. */
+ SequenceModifierData *smd;
+ for (smd = user_seq->modifiers.first; smd; smd = smd->next) {
+ if (smd->mask_sequence == seq) {
+ smd->mask_sequence = NULL;
+ }
+ }
+
+ /* Remove effects, that use seq. */
+ if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) ||
+ (user_seq->seq3 && user_seq->seq3 == seq)) {
+ user_seq->flag |= SEQ_FLAG_DELETE;
+ /* Strips can be used as mask even if not in same seqbase. */
+ sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq);
+ }
+ }
+}
+
+/* Flag seq and its users (effects) for removal. */
+void BKE_sequencer_flag_for_removal(Scene *scene, ListBase *seqbase, Sequence *seq)
+{
+ if (seq == NULL || (seq->flag & SEQ_FLAG_DELETE) != 0) {
+ return;
+ }
+
+ /* Flag and remove meta children. */
+ if (seq->type == SEQ_TYPE_META) {
+ LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) {
+ BKE_sequencer_flag_for_removal(scene, &seq->seqbase, meta_child);
+ }
+ }
+
+ seq->flag |= SEQ_FLAG_DELETE;
+ sequencer_flag_users_for_removal(scene, seqbase, seq);
+}
+
+/* Remove all flagged sequences, return true if sequence is removed. */
+void BKE_sequencer_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
+{
+ LISTBASE_FOREACH_MUTABLE (Sequence *, seq, seqbase) {
+ if (seq->flag & SEQ_FLAG_DELETE) {
+ if (seq->type == SEQ_TYPE_META) {
+ BKE_sequencer_remove_flagged_sequences(scene, &seq->seqbase);
+ }
+ BLI_remlink(seqbase, seq);
+ BKE_sequence_free(scene, seq, true);
+ }
+ }
+}
+
void BKE_sequencer_check_uuids_unique_and_report(const Scene *scene)
{
if (scene->ed == NULL) {
diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c
index 2923298c5d5..b3d350f5ccd 100644
--- a/source/blender/blenkernel/intern/shader_fx.c
+++ b/source/blender/blenkernel/intern/shader_fx.c
@@ -160,9 +160,8 @@ const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type)
if (type < NUM_SHADER_FX_TYPES && type > 0 && shader_fx_types[type]->name[0] != '\0') {
return shader_fx_types[type];
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/**
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 29f4c7dc6c1..0ff5bdda9e9 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -136,30 +136,29 @@ bool BKE_shrinkwrap_init_tree(
return data->bvh != NULL;
}
- else {
- if (mesh->totpoly <= 0) {
- return false;
- }
- data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_LOOPTRI, 4);
+ if (mesh->totpoly <= 0) {
+ return false;
+ }
- if (data->bvh == NULL) {
- return false;
- }
+ data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_LOOPTRI, 4);
- if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
- data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
- if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
- data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
- }
- }
+ if (data->bvh == NULL) {
+ return false;
+ }
- if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
- data->boundary = mesh->runtime.shrinkwrap_data;
+ if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) {
+ data->pnors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
+ if ((mesh->flag & ME_AUTOSMOOTH) != 0) {
+ data->clnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
}
+ }
- return true;
+ if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) {
+ data->boundary = mesh->runtime.shrinkwrap_data;
}
+
+ return true;
}
/* Frees the tree data if necessary. */
@@ -761,7 +760,7 @@ static void target_project_tri_deviation(void *userdata, const float x[3], float
{
TargetProjectTriData *data = userdata;
- float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]};
+ const float w[3] = {x[0], x[1], 1.0f - x[0] - x[1]};
interp_v3_v3v3v3(data->co_interp, data->vtri_co[0], data->vtri_co[1], data->vtri_co[2], w);
interp_v3_v3v3v3(data->no_interp, data->vtri_no[0], data->vtri_no[1], data->vtri_no[2], w);
diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc
index 95340e4e29c..c0fc8fcb464 100644
--- a/source/blender/blenkernel/intern/simulation.cc
+++ b/source/blender/blenkernel/intern/simulation.cc
@@ -112,8 +112,8 @@ static void simulation_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons
BKE_simulation_state_copy_data(state_src, state_dst);
}
- BLI_duplicatelist(&simulation_dst->persistent_data_handles,
- &simulation_src->persistent_data_handles);
+ BLI_listbase_clear(&simulation_dst->dependencies);
+ BLI_duplicatelist(&simulation_dst->dependencies, &simulation_src->dependencies);
}
static void simulation_free_data(ID *id)
@@ -130,7 +130,7 @@ static void simulation_free_data(ID *id)
BKE_simulation_state_remove_all(simulation);
- BLI_freelistN(&simulation->persistent_data_handles);
+ BLI_freelistN(&simulation->dependencies);
}
static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
@@ -140,9 +140,8 @@ static void simulation_foreach_id(ID *id, LibraryForeachIDData *data)
/* nodetree **are owned by IDs**, treat them as mere sub-data and not real ID! */
BKE_library_foreach_ID_embedded(data, (ID **)&simulation->nodetree);
}
- LISTBASE_FOREACH (
- PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
- BKE_LIB_FOREACHID_PROCESS_ID(data, handle_item->id, IDWALK_CB_USER);
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BKE_LIB_FOREACHID_PROCESS_ID(data, dependency->id, IDWALK_CB_USER);
}
}
@@ -284,6 +283,14 @@ void BKE_simulation_data_update(Depsgraph *depsgraph, Scene *scene, Simulation *
blender::sim::update_simulation_in_depsgraph(depsgraph, scene, simulation);
}
+void BKE_simulation_update_dependencies(Simulation *simulation, Main *bmain)
+{
+ bool dependencies_changed = blender::sim::update_simulation_dependencies(simulation);
+ if (dependencies_changed) {
+ DEG_relations_tag_update(bmain);
+ }
+}
+
using StateTypeMap = blender::Map<std::string, std::unique_ptr<SimulationStateType>>;
template<typename T>
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index b7b325644ca..1d56db3779a 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1051,7 +1051,7 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]),
/* --- the aabb section*/
/* +++ the face external section*/
-static int sb_detect_face_pointCached(float face_v1[3],
+static int sb_detect_face_pointCached(const float face_v1[3],
const float face_v2[3],
const float face_v3[3],
float *damp,
@@ -1149,7 +1149,7 @@ static int sb_detect_face_pointCached(float face_v1[3],
return deflected;
}
-static int sb_detect_face_collisionCached(float face_v1[3],
+static int sb_detect_face_collisionCached(const float face_v1[3],
const float face_v2[3],
const float face_v3[3],
float *damp,
@@ -1328,7 +1328,7 @@ static void scan_for_ext_face_forces(Object *ob, float timenow)
/* +++ the spring external section*/
-static int sb_detect_edge_collisionCached(float edge_v1[3],
+static int sb_detect_edge_collisionCached(const float edge_v1[3],
const float edge_v2[3],
float *damp,
float force[3],
@@ -3211,12 +3211,11 @@ static int object_has_edges(Object *ob)
if (ob->type == OB_MESH) {
return ((Mesh *)ob->data)->totedge;
}
- else if (ob->type == OB_LATTICE) {
+ if (ob->type == OB_LATTICE) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
/* SB global visible functions */
@@ -3563,7 +3562,7 @@ void sbObjectStep(struct Depsgraph *depsgraph,
BKE_ptcache_invalidate(cache);
return;
}
- else if (framenr > endframe) {
+ if (framenr > endframe) {
framenr = endframe;
}
@@ -3631,7 +3630,7 @@ void sbObjectStep(struct Depsgraph *depsgraph,
return;
}
- else if (cache_result == PTCACHE_READ_OLD) {
+ if (cache_result == PTCACHE_READ_OLD) {
/* pass */
}
else if (/*ob->id.lib || */
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 1fcfc9b060f..060174c94a5 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -898,9 +898,8 @@ double BKE_sound_sync_scene(Scene *scene)
if (scene->audio.flag & AUDIO_SYNC) {
return AUD_getSynchronizerPosition(scene->playback_handle);
}
- else {
- return AUD_Handle_getPosition(scene->playback_handle);
- }
+
+ return AUD_Handle_getPosition(scene->playback_handle);
}
return NAN_FLT;
}
@@ -922,9 +921,8 @@ int BKE_sound_scene_playing(Scene *scene)
if (scene->audio.flag & AUDIO_SYNC) {
return AUD_isSynchronizerPlaying();
}
- else {
- return -1;
- }
+
+ return -1;
}
void BKE_sound_free_waveform(bSound *sound)
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c
index 46341652544..68626bdc8dd 100644
--- a/source/blender/blenkernel/intern/studiolight.c
+++ b/source/blender/blenkernel/intern/studiolight.c
@@ -366,23 +366,22 @@ static float *studiolight_multilayer_convert_pass(ImBuf *ibuf,
if (channels == 4) {
return rect;
}
- else {
- float *new_rect = MEM_callocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__);
-
- IMB_buffer_float_from_float(new_rect,
- rect,
- channels,
- IB_PROFILE_LINEAR_RGB,
- IB_PROFILE_LINEAR_RGB,
- false,
- ibuf->x,
- ibuf->y,
- ibuf->x,
- ibuf->x);
- MEM_freeN(rect);
- return new_rect;
- }
+ float *new_rect = MEM_callocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__);
+
+ IMB_buffer_float_from_float(new_rect,
+ rect,
+ channels,
+ IB_PROFILE_LINEAR_RGB,
+ IB_PROFILE_LINEAR_RGB,
+ false,
+ ibuf->x,
+ ibuf->y,
+ ibuf->x,
+ ibuf->x);
+
+ MEM_freeN(rect);
+ return new_rect;
}
static void studiolight_multilayer_addpass(void *base,
@@ -1229,12 +1228,11 @@ static int studiolight_cmp(const void *a, const void *b)
if (flagorder1 < flagorder2) {
return -1;
}
- else if (flagorder1 > flagorder2) {
+ if (flagorder1 > flagorder2) {
return 1;
}
- else {
- return BLI_strcasecmp(sl1->name, sl2->name);
- }
+
+ return BLI_strcasecmp(sl1->name, sl2->name);
}
/* icons */
@@ -1245,7 +1243,7 @@ static int studiolight_cmp(const void *a, const void *b)
static uint alpha_circle_mask(float u, float v, float inner_edge, float outer_edge)
{
/* Coords from center. */
- float co[2] = {u - 0.5f, v - 0.5f};
+ const float co[2] = {u - 0.5f, v - 0.5f};
float dist = len_v2(co);
float alpha = 1.0f + (inner_edge - dist) / (outer_edge - inner_edge);
uint mask = (uint)floorf(255.0f * min_ff(max_ff(alpha, 0.0f), 1.0f));
@@ -1277,7 +1275,7 @@ static void studiolight_radiance_preview(uint *icon_buffer, StudioLight *sl)
uint alphamask = alpha_circle_mask(dx, dy, 0.5f - texel_size[0], 0.5f);
if (alphamask != 0) {
float normal[3], direction[3], color[4];
- float incoming[3] = {0.0f, 0.0f, -1.0f};
+ const float incoming[3] = {0.0f, 0.0f, -1.0f};
sphere_normal_from_uv(normal, dx, dy);
reflect_v3_v3v3(direction, incoming, normal);
/* We want to see horizon not poles. */
@@ -1496,10 +1494,9 @@ struct StudioLight *BKE_studiolight_find(const char *name, int flag)
if ((sl->flag & flag)) {
return sl;
}
- else {
- /* flags do not match, so use default */
- return BKE_studiolight_find_default(flag);
- }
+
+ /* flags do not match, so use default */
+ return BKE_studiolight_find_default(flag);
}
}
/* When not found, use the default studio light */
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c
index bc1b79f62c5..c992990e0a0 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg.c
@@ -1618,7 +1618,7 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int
return point_index - 1;
}
-/* When the point index corresponds to a grid corner, returs the point index which corresponds to
+/* When the point index corresponds to a grid corner, returns the point index which corresponds to
* the corner of the adjacent grid, as the adjacent edge has two separate points for each grid
* corner at the middle of the edge. */
static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg,
@@ -1650,7 +1650,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg,
if (include_duplicates) {
num_duplicates += num_adjacent_faces - 1;
if (is_corner) {
- /* When the coord is a grid corner, add an extra duplicate per adajacent grid in all adjacent
+ /* When the coord is a grid corner, add an extra duplicate per adjacent grid in all adjacent
* faces to the edge. */
num_duplicates += num_adjacent_faces;
}
diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
index 617f37834f9..a63c2994687 100644
--- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c
+++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
@@ -128,10 +128,10 @@ BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid,
if (x == 0 && y == 0) {
return AVERAGE_WITH_ALL;
}
- else if (x == 0) {
+ if (x == 0) {
return AVERAGE_WITH_PREV;
}
- else if (y == 0) {
+ if (y == 0) {
return AVERAGE_WITH_NEXT;
}
return AVERAGE_WITH_NONE;
@@ -321,9 +321,8 @@ static int displacement_get_face_corner(MultiresDisplacementData *data,
float dummy_corner_u, dummy_corner_v;
return BKE_subdiv_rotate_quad_to_corner(u, v, &dummy_corner_u, &dummy_corner_v);
}
- else {
- return poly_corner->corner;
- }
+
+ return poly_corner->corner;
}
static void initialize(SubdivDisplacement *displacement)
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 1c10a9a1935..baee8a80f5a 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -46,7 +46,7 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv)
* or when OpenSubdiv is disabled */
return false;
}
- else if (subdiv->evaluator == NULL) {
+ if (subdiv->evaluator == NULL) {
BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner(subdiv->topology_refiner);
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE);
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index ff7f6fad5f0..37cca12721a 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -1040,7 +1040,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
static void rotate_indices(const int rot, int *a, int *b, int *c, int *d)
{
- int values[4] = {*a, *b, *c, *d};
+ const int values[4] = {*a, *b, *c, *d};
*a = values[(0 - rot + 4) % 4];
*b = values[(1 - rot + 4) % 4];
*c = values[(2 - rot + 4) % 4];
@@ -1123,10 +1123,10 @@ static int subdiv_foreach_loops_corner_index(const float u,
if (u + du <= 0.5f && v + dv <= 0.5f) {
return 0;
}
- else if (u >= 0.5f && v + dv <= 0.5f) {
+ if (u >= 0.5f && v + dv <= 0.5f) {
return 1;
}
- else if (u >= 0.5f && v >= 0.5f) {
+ if (u >= 0.5f && v >= 0.5f) {
return 2;
}
return 3;
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 7a0a5645b80..98386a3356a 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -203,12 +203,11 @@ static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize)
if (x == 0) {
return v0idx;
}
- else if (x == edgeSize - 1) {
+ if (x == edgeSize - 1) {
return v1idx;
}
- else {
- return edgeBase + x - 1;
- }
+
+ return edgeBase + x - 1;
}
static int getFaceIndex(
@@ -221,42 +220,39 @@ static int getFaceIndex(
CCGVert *v = ccgSubSurf_getFaceVert(f, S);
return *((int *)ccgSubSurf_getVertUserData(ss, v));
}
- else if (x == gridSize - 1) {
+ if (x == gridSize - 1) {
CCGVert *v = ccgSubSurf_getFaceVert(f, S);
CCGEdge *e = ccgSubSurf_getFaceEdge(f, S);
int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
if (v == ccgSubSurf_getEdgeVert0(e)) {
return edgeBase + (gridSize - 1 - y) - 1;
}
- else {
- return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
- }
+
+ return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - y) - 1);
}
- else if (y == gridSize - 1) {
+ if (y == gridSize - 1) {
CCGVert *v = ccgSubSurf_getFaceVert(f, S);
CCGEdge *e = ccgSubSurf_getFaceEdge(f, (S + numVerts - 1) % numVerts);
int edgeBase = *((int *)ccgSubSurf_getEdgeUserData(ss, e));
if (v == ccgSubSurf_getEdgeVert0(e)) {
return edgeBase + (gridSize - 1 - x) - 1;
}
- else {
- return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
- }
+
+ return edgeBase + (edgeSize - 2 - 1) - ((gridSize - 1 - x) - 1);
}
- else if (x == 0 && y == 0) {
+ if (x == 0 && y == 0) {
return faceBase;
}
- else if (x == 0) {
+ if (x == 0) {
S = (S + numVerts - 1) % numVerts;
return faceBase + 1 + (gridSize - 2) * S + (y - 1);
}
- else if (y == 0) {
+ if (y == 0) {
return faceBase + 1 + (gridSize - 2) * S + (x - 1);
}
- else {
- return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
- (y - 1) * (gridSize - 2) + (x - 1);
- }
+
+ return faceBase + 1 + (gridSize - 2) * numVerts + S * (gridSize - 2) * (gridSize - 2) +
+ (y - 1) * (gridSize - 2) + (x - 1);
}
static void get_face_uv_map_vert(
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 5f85e1a1664..8a055423d6f 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -812,9 +812,8 @@ int txt_calc_tab_right(TextLine *tl, int ch)
return i - ch;
}
- else {
- return 0;
- }
+
+ return 0;
}
void txt_move_left(Text *text, const bool sel)
@@ -1664,9 +1663,8 @@ int txt_find_string(Text *text, const char *findstr, int wrap, int match_case)
txt_move_to(text, newl, newc + strlen(findstr), 1);
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
/** \} */
@@ -1797,7 +1795,7 @@ void txt_delete_char(Text *text)
txt_make_dirty(text);
return;
}
- else if (text->curc == text->curl->len) { /* Appending two lines */
+ if (text->curc == text->curl->len) { /* Appending two lines */
if (text->curl->next) {
txt_combine_lines(text, text->curl, text->curl->next);
txt_pop_sel(text);
@@ -1844,7 +1842,7 @@ void txt_backspace_char(Text *text)
txt_make_dirty(text);
return;
}
- else if (text->curc == 0) { /* Appending two lines */
+ if (text->curc == 0) { /* Appending two lines */
if (!text->curl->prev) {
return;
}
@@ -2052,10 +2050,9 @@ static void txt_select_prefix(Text *text, const char *add, bool skip_blank_lines
}
break;
}
- else {
- text->curl = text->curl->next;
- num++;
- }
+
+ text->curl = text->curl->next;
+ num++;
}
while (num > 0) {
@@ -2140,10 +2137,9 @@ static bool txt_select_unprefix(Text *text, const char *remove, const bool requi
}
break;
}
- else {
- text->curl = text->curl->next;
- num++;
- }
+
+ text->curl = text->curl->next;
+ num++;
}
if (unindented_first) {
@@ -2253,9 +2249,8 @@ int txt_setcurr_tab_spaces(Text *text, int space)
if (i == text->curc) {
return i;
}
- else {
- i++;
- }
+
+ i++;
}
if (strstr(text->curl->line, word)) {
/* if we find a ':' on this line, then add a tab but not if it is:
@@ -2270,7 +2265,7 @@ int txt_setcurr_tab_spaces(Text *text, int space)
if (ch == '#') {
break;
}
- else if (ch == ':') {
+ if (ch == ':') {
is_indent = 1;
}
else if (ch != ' ' && ch != '\t') {
@@ -2309,7 +2304,7 @@ int text_check_bracket(const char ch)
if (ch == opens[a]) {
return a + 1;
}
- else if (ch == close[a]) {
+ if (ch == close[a]) {
return -(a + 1);
}
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index e2c3c20e36e..8d5a0497e28 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -664,11 +664,11 @@ bool BKE_texture_dependsOnTime(const struct Tex *texture)
if (texture->ima && BKE_image_is_animated(texture->ima)) {
return true;
}
- else if (texture->adt) {
+ if (texture->adt) {
/* assume anything in adt means the texture is animated */
return true;
}
- else if (texture->type == TEX_NOISE) {
+ if (texture->type == TEX_NOISE) {
/* noise always varies with time */
return true;
}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index f17467e4a26..8a1ebaf722b 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1188,38 +1188,36 @@ MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track,
return old_marker;
}
- else {
- int a = track->markersnr;
- /* find position in array where to add new marker */
- while (a--) {
- if (track->markers[a].framenr < marker->framenr) {
- break;
- }
+ int a = track->markersnr;
+
+ /* find position in array where to add new marker */
+ while (a--) {
+ if (track->markers[a].framenr < marker->framenr) {
+ break;
}
+ }
- track->markersnr++;
+ track->markersnr++;
- if (track->markers) {
- track->markers = MEM_reallocN(track->markers,
- sizeof(MovieTrackingMarker) * track->markersnr);
- }
- else {
- track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
- }
+ if (track->markers) {
+ track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
+ }
+ else {
+ track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
+ }
- /* shift array to "free" space for new marker */
- memmove(track->markers + a + 2,
- track->markers + a + 1,
- (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
+ /* shift array to "free" space for new marker */
+ memmove(track->markers + a + 2,
+ track->markers + a + 1,
+ (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
- /* put new marker */
- track->markers[a + 1] = *marker;
+ /* put new marker */
+ track->markers[a + 1] = *marker;
- track->last_marker = a + 1;
+ track->last_marker = a + 1;
- return &track->markers[a + 1];
- }
+ return &track->markers[a + 1];
}
void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
@@ -1337,21 +1335,20 @@ MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int fram
/* if there's no marker for exact position, use nearest marker from left side */
return &track->markers[a - 1];
}
- else {
- while (a >= 0 && track->markers[a].framenr >= framenr) {
- if (track->markers[a].framenr == framenr) {
- track->last_marker = a;
- return &track->markers[a];
- }
+ while (a >= 0 && track->markers[a].framenr >= framenr) {
+ if (track->markers[a].framenr == framenr) {
+ track->last_marker = a;
- a--;
+ return &track->markers[a];
}
- /* if there's no marker for exact position, use nearest marker from left side */
- return &track->markers[a];
+ a--;
}
+ /* if there's no marker for exact position, use nearest marker from left side */
+ return &track->markers[a];
+
return NULL;
}
@@ -1655,32 +1652,31 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTra
return old_plane_marker;
}
- else {
- int a = plane_track->markersnr;
- /* Find position in array where to add new marker. */
- /* TODO(sergey): we could use bisect to speed things up. */
- while (a--) {
- if (plane_track->markers[a].framenr < plane_marker->framenr) {
- break;
- }
+ int a = plane_track->markersnr;
+
+ /* Find position in array where to add new marker. */
+ /* TODO(sergey): we could use bisect to speed things up. */
+ while (a--) {
+ if (plane_track->markers[a].framenr < plane_marker->framenr) {
+ break;
}
+ }
- plane_track->markersnr++;
- plane_track->markers = MEM_reallocN(plane_track->markers,
- sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr);
+ plane_track->markersnr++;
+ plane_track->markers = MEM_reallocN(plane_track->markers,
+ sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr);
- /* Shift array to "free" space for new marker. */
- memmove(plane_track->markers + a + 2,
- plane_track->markers + a + 1,
- (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker));
+ /* Shift array to "free" space for new marker. */
+ memmove(plane_track->markers + a + 2,
+ plane_track->markers + a + 1,
+ (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker));
- /* Put new marker to an array. */
- plane_track->markers[a + 1] = *plane_marker;
- plane_track->last_marker = a + 1;
+ /* Put new marker to an array. */
+ plane_track->markers[a + 1] = *plane_marker;
+ plane_track->last_marker = a + 1;
- return &plane_track->markers[a + 1];
- }
+ return &plane_track->markers[a + 1];
}
void BKE_tracking_plane_marker_delete(MovieTrackingPlaneTrack *plane_track, int framenr)
@@ -1748,21 +1744,20 @@ MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(MovieTrackingPlaneTrack
/* If there's no marker for exact position, use nearest marker from left side. */
return &plane_track->markers[a - 1];
}
- else {
- while (a >= 0 && plane_track->markers[a].framenr >= framenr) {
- if (plane_track->markers[a].framenr == framenr) {
- plane_track->last_marker = a;
- return &plane_track->markers[a];
- }
+ while (a >= 0 && plane_track->markers[a].framenr >= framenr) {
+ if (plane_track->markers[a].framenr == framenr) {
+ plane_track->last_marker = a;
- a--;
+ return &plane_track->markers[a];
}
- /* If there's no marker for exact position, use nearest marker from left side. */
- return &plane_track->markers[a];
+ a--;
}
+ /* If there's no marker for exact position, use nearest marker from left side. */
+ return &plane_track->markers[a];
+
return NULL;
}
@@ -1988,18 +1983,16 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru
if (nearest) {
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
if (framenr > cameras[reconstruction->camnr - 1].framenr) {
if (nearest) {
return reconstruction->camnr - 1;
}
- else {
- return -1;
- }
+
+ return -1;
}
if (reconstruction->last_camera < reconstruction->camnr) {
@@ -2020,9 +2013,8 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru
if (nearest) {
return a - 1;
}
- else {
- break;
- }
+
+ break;
}
if (d < 0 && cfra < framenr) {
@@ -2030,9 +2022,8 @@ static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstru
if (nearest) {
return a;
}
- else {
- break;
- }
+
+ break;
}
if (cfra == framenr) {
@@ -2705,9 +2696,8 @@ static int channels_alpha_sort(const void *a, const void *b)
if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int channels_total_track_sort(const void *a, const void *b)
@@ -2718,9 +2708,8 @@ static int channels_total_track_sort(const void *a, const void *b)
if (channel_a->total_frames > channel_b->total_frames) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int channels_longest_segment_sort(const void *a, const void *b)
@@ -2731,9 +2720,8 @@ static int channels_longest_segment_sort(const void *a, const void *b)
if (channel_a->max_segment > channel_b->max_segment) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int channels_average_error_sort(const void *a, const void *b)
@@ -2744,9 +2732,8 @@ static int channels_average_error_sort(const void *a, const void *b)
if (channel_a->track->error > channel_b->track->error) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int channels_alpha_inverse_sort(const void *a, const void *b)
@@ -2754,9 +2741,8 @@ static int channels_alpha_inverse_sort(const void *a, const void *b)
if (channels_alpha_sort(a, b)) {
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
static int channels_total_track_inverse_sort(const void *a, const void *b)
@@ -2764,9 +2750,8 @@ static int channels_total_track_inverse_sort(const void *a, const void *b)
if (channels_total_track_sort(a, b)) {
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
static int channels_longest_segment_inverse_sort(const void *a, const void *b)
@@ -2774,9 +2759,8 @@ static int channels_longest_segment_inverse_sort(const void *a, const void *b)
if (channels_longest_segment_sort(a, b)) {
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
static int channels_average_error_inverse_sort(const void *a, const void *b)
@@ -2787,9 +2771,8 @@ static int channels_average_error_inverse_sort(const void *a, const void *b)
if (channel_a->track->error < channel_b->track->error) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
/* Calculate frames segments at which track is tracked continuously. */
@@ -2965,7 +2948,7 @@ static int coverage_from_count(int count)
if (count < 8) {
return TRACKING_COVERAGE_BAD;
}
- else if (count < 16) {
+ if (count < 16) {
return TRACKING_COVERAGE_ACCEPTABLE;
}
return TRACKING_COVERAGE_OK;
diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c
index 46870a03e62..7df8bf62b16 100644
--- a/source/blender/blenkernel/intern/tracking_solver.c
+++ b/source/blender/blenkernel/intern/tracking_solver.c
@@ -335,7 +335,7 @@ bool BKE_tracking_reconstruction_check(MovieTracking *tracking,
/* TODO: check for number of tracks? */
return true;
}
- else if ((tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) == 0) {
+ if ((tracking->settings.reconstruction_flag & TRACKING_USE_KEYFRAME_SELECTION) == 0) {
/* automatic keyframe selection does not require any pre-process checks */
if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) {
BLI_strncpy(error_msg,
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index e09e92588c6..46e3e10b01b 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -215,7 +215,7 @@ static void use_values_from_fcurves(StabContext *ctx, bool toggle)
/* Prepare per call private working area.
* Used for access to possibly animated values: retrieve available F-curves.
*/
-static StabContext *initialize_stabilization_working_context(MovieClip *clip)
+static StabContext *init_stabilization_working_context(MovieClip *clip)
{
StabContext *ctx = MEM_callocN(sizeof(StabContext), "2D stabilization animation runtime data");
ctx->clip = clip;
@@ -357,9 +357,8 @@ static MovieTrackingMarker *get_closest_marker(StabContext *ctx,
if ((next_higher - ref_frame) < (ref_frame - next_lower)) {
return BKE_tracking_marker_get_exact(track, next_higher);
}
- else {
- return BKE_tracking_marker_get_exact(track, next_lower);
- }
+
+ return BKE_tracking_marker_get_exact(track, next_lower);
}
/* Retrieve tracking data, if available and applicable for this frame.
@@ -377,11 +376,10 @@ static MovieTrackingMarker *get_tracking_data_point(StabContext *ctx,
*r_weight = get_animated_weight(ctx, track, framenr);
return marker;
}
- else {
- /* No marker at this frame (=gap) or marker disabled. */
- *r_weight = 0.0f;
- return NULL;
- }
+
+ /* No marker at this frame (=gap) or marker disabled. */
+ *r_weight = 0.0f;
+ return NULL;
}
/* Define the reference point for rotation/scale measurement and compensation.
@@ -841,14 +839,14 @@ static int establish_track_initialization_order(StabContext *ctx, TrackInitOrder
*
* NOTE: when done, this track is marked as initialized
*/
-static void initialize_track_for_stabilization(StabContext *ctx,
- MovieTrackingTrack *track,
- int reference_frame,
- float aspect,
- const float average_translation[2],
- const float pivot[2],
- const float average_angle,
- const float average_scale_step)
+static void init_track_for_stabilization(StabContext *ctx,
+ MovieTrackingTrack *track,
+ int reference_frame,
+ float aspect,
+ const float average_translation[2],
+ const float pivot[2],
+ const float average_angle,
+ const float average_scale_step)
{
float pos[2], angle, len;
TrackStabilizationBase *local_data = access_stabilization_baseline_data(ctx, track);
@@ -876,7 +874,7 @@ static void initialize_track_for_stabilization(StabContext *ctx,
local_data->is_init_for_stabilization = true;
}
-static void initialize_all_tracks(StabContext *ctx, float aspect)
+static void init_all_tracks(StabContext *ctx, float aspect)
{
size_t track_len = 0;
MovieClip *clip = ctx->clip;
@@ -936,14 +934,14 @@ static void initialize_all_tracks(StabContext *ctx, float aspect)
&average_angle,
&average_scale_step);
}
- initialize_track_for_stabilization(ctx,
- track,
- reference_frame,
- aspect,
- average_translation,
- pivot,
- average_angle,
- average_scale_step);
+ init_track_for_stabilization(ctx,
+ track,
+ reference_frame,
+ aspect,
+ average_translation,
+ pivot,
+ average_angle,
+ average_scale_step);
}
cleanup:
@@ -1094,7 +1092,7 @@ static void stabilization_data_to_mat4(float pixel_aspect,
{
float translation_mat[4][4], rotation_mat[4][4], scale_mat[4][4], pivot_mat[4][4],
inv_pivot_mat[4][4], aspect_mat[4][4], inv_aspect_mat[4][4];
- float scale_vector[3] = {scale, scale, 1.0f};
+ const float scale_vector[3] = {scale, scale, 1.0f};
unit_m4(translation_mat);
unit_m4(rotation_mat);
@@ -1257,9 +1255,9 @@ static float calculate_autoscale_factor(StabContext *ctx, int size, float aspect
*/
static StabContext *init_stabilizer(MovieClip *clip, int size, float aspect)
{
- StabContext *ctx = initialize_stabilization_working_context(clip);
+ StabContext *ctx = init_stabilization_working_context(clip);
BLI_assert(ctx != NULL);
- initialize_all_tracks(ctx, aspect);
+ init_all_tracks(ctx, aspect);
if (ctx->stab->flag & TRACKING_AUTOSCALE) {
ctx->stab->scale = 1.0;
ctx->stab->scale = calculate_autoscale_factor(ctx, size, aspect);
diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c
index 0809e8dda6d..0a0f81f7829 100644
--- a/source/blender/blenkernel/intern/undo_system.c
+++ b/source/blender/blenkernel/intern/undo_system.c
@@ -476,9 +476,8 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack,
undosys_stack_validate(ustack, false);
return us;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, bContext *C, const char *name)
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index efe10b02940..b8d86f0dc5b 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -970,9 +970,8 @@ double bUnit_PreferredInputUnitScalar(const struct UnitSettings *settings, int t
if (unit) {
return unit->scalar;
}
- else {
- return bUnit_BaseScalar(units.system, type);
- }
+
+ return bUnit_BaseScalar(units.system, type);
}
/* make a copy of the string that replaces the units with numbers
@@ -1155,9 +1154,8 @@ double bUnit_BaseScalar(int system, int type)
if (usys) {
return unit_default(usys)->scalar;
}
- else {
- return 1.0;
- }
+
+ return 1.0;
}
/* external access */
diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc
index 633ad250a67..54fb0f612d1 100644
--- a/source/blender/blenkernel/intern/volume.cc
+++ b/source/blender/blenkernel/intern/volume.cc
@@ -367,9 +367,8 @@ struct VolumeGrid {
if (is_loaded && entry && !entry->error_msg.empty()) {
return entry->error_msg.c_str();
}
- else {
- return NULL;
- }
+
+ return NULL;
}
const bool grid_is_loaded() const
@@ -1087,34 +1086,34 @@ VolumeGridType BKE_volume_grid_type(const VolumeGrid *volume_grid)
if (grid->isType<openvdb::FloatGrid>()) {
return VOLUME_GRID_FLOAT;
}
- else if (grid->isType<openvdb::Vec3fGrid>()) {
+ if (grid->isType<openvdb::Vec3fGrid>()) {
return VOLUME_GRID_VECTOR_FLOAT;
}
- else if (grid->isType<openvdb::BoolGrid>()) {
+ if (grid->isType<openvdb::BoolGrid>()) {
return VOLUME_GRID_BOOLEAN;
}
- else if (grid->isType<openvdb::DoubleGrid>()) {
+ if (grid->isType<openvdb::DoubleGrid>()) {
return VOLUME_GRID_DOUBLE;
}
- else if (grid->isType<openvdb::Int32Grid>()) {
+ if (grid->isType<openvdb::Int32Grid>()) {
return VOLUME_GRID_INT;
}
- else if (grid->isType<openvdb::Int64Grid>()) {
+ if (grid->isType<openvdb::Int64Grid>()) {
return VOLUME_GRID_INT64;
}
- else if (grid->isType<openvdb::Vec3IGrid>()) {
+ if (grid->isType<openvdb::Vec3IGrid>()) {
return VOLUME_GRID_VECTOR_INT;
}
- else if (grid->isType<openvdb::Vec3dGrid>()) {
+ if (grid->isType<openvdb::Vec3dGrid>()) {
return VOLUME_GRID_VECTOR_DOUBLE;
}
- else if (grid->isType<openvdb::StringGrid>()) {
+ if (grid->isType<openvdb::StringGrid>()) {
return VOLUME_GRID_STRING;
}
- else if (grid->isType<openvdb::MaskGrid>()) {
+ if (grid->isType<openvdb::MaskGrid>()) {
return VOLUME_GRID_MASK;
}
- else if (grid->isType<openvdb::points::PointDataGrid>()) {
+ if (grid->isType<openvdb::points::PointDataGrid>()) {
return VOLUME_GRID_POINTS;
}
#else
diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc
index 135c6f78fef..98d3617c822 100644
--- a/source/blender/blenkernel/intern/volume_render.cc
+++ b/source/blender/blenkernel/intern/volume_render.cc
@@ -363,7 +363,6 @@ float BKE_volume_density_scale(const Volume *volume, const float matrix[4][4])
mul_mat3_m4_v3(matrix, unit);
return 1.0f / len_v3(unit);
}
- else {
- return 1.0f;
- }
+
+ return 1.0f;
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 4625fd76293..f653a190704 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -157,9 +157,8 @@ static void *workspace_relation_get_data_matching_parent(const ListBase *relatio
if (relation != NULL) {
return relation->value;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
/**
@@ -397,10 +396,9 @@ bool BKE_workspace_owner_id_check(const WorkSpace *workspace, const char *owner_
if ((*owner_id == '\0') || ((workspace->flags & WORKSPACE_USE_FILTER_BY_ORIGIN) == 0)) {
return true;
}
- else {
- /* We could use hash lookup, for now this list is highly likely under < ~16 items. */
- return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
- }
+
+ /* We could use hash lookup, for now this list is highly likely under < ~16 items. */
+ return BLI_findstring(&workspace->owner_ids, owner_id, offsetof(wmOwnerID, name)) != NULL;
}
void BKE_workspace_id_tag_all_visible(Main *bmain, int tag)
diff --git a/source/blender/blenlib/BLI_dial_2d.h b/source/blender/blenlib/BLI_dial_2d.h
index f43237f6b75..fdbc3d4430b 100644
--- a/source/blender/blenlib/BLI_dial_2d.h
+++ b/source/blender/blenlib/BLI_dial_2d.h
@@ -37,7 +37,7 @@
* float angle;
* Dial *dial;
*
- * dial = BLI_dial_initialize(start_position, threshold);
+ * dial = BLI_dial_init(start_position, threshold);
*
* angle = BLI_dial_angle(dial, current_position);
*
@@ -51,7 +51,7 @@ extern "C" {
typedef struct Dial Dial;
-Dial *BLI_dial_initialize(const float start_position[2], float threshold);
+Dial *BLI_dial_init(const float start_position[2], float threshold);
float BLI_dial_angle(Dial *dial, const float current_position[2]);
diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh
index 2d6dbb1f600..a026a85dd62 100644
--- a/source/blender/blenlib/BLI_dot_export.hh
+++ b/source/blender/blenlib/BLI_dot_export.hh
@@ -43,9 +43,8 @@ class NodePort;
class DirectedEdge;
class UndirectedEdge;
class Cluster;
-class AttributeList;
-class AttributeList {
+class Attributes {
private:
Map<std::string, std::string> attributes_;
@@ -56,11 +55,15 @@ class AttributeList {
{
attributes_.add_overwrite(key, value);
}
+
+ void set(StringRef key, float value)
+ {
+ attributes_.add_overwrite(key, std::to_string(value));
+ }
};
class Graph {
private:
- AttributeList attributes_;
Vector<std::unique_ptr<Node>> nodes_;
Vector<std::unique_ptr<Cluster>> clusters_;
@@ -71,19 +74,17 @@ class Graph {
friend Node;
public:
+ Attributes attributes;
+
+ public:
Node &new_node(StringRef label);
Cluster &new_cluster(StringRef label = "");
void export__declare_nodes_and_clusters(std::stringstream &ss) const;
- void set_attribute(StringRef key, StringRef value)
- {
- attributes_.set(key, value);
- }
-
void set_rankdir(Attr_rankdir rankdir)
{
- this->set_attribute("rankdir", rankdir_to_string(rankdir));
+ attributes.set("rankdir", rankdir_to_string(rankdir));
}
void set_random_cluster_bgcolors();
@@ -91,7 +92,6 @@ class Graph {
class Cluster {
private:
- AttributeList attributes_;
Graph &graph_;
Cluster *parent_ = nullptr;
Set<Cluster *> children_;
@@ -100,6 +100,9 @@ class Cluster {
friend Graph;
friend Node;
+ public:
+ Attributes attributes;
+
Cluster(Graph &graph) : graph_(graph)
{
}
@@ -107,9 +110,9 @@ class Cluster {
public:
void export__declare_nodes_and_clusters(std::stringstream &ss) const;
- void set_attribute(StringRef key, StringRef value)
+ std::string name() const
{
- attributes_.set(key, value);
+ return "cluster_" + std::to_string((uintptr_t)this);
}
void set_parent_cluster(Cluster *cluster);
@@ -118,53 +121,52 @@ class Cluster {
this->set_parent_cluster(&cluster);
}
+ Cluster *parent_cluster()
+ {
+ return parent_;
+ }
+
void set_random_cluster_bgcolors();
+
+ bool contains(Node &node) const;
};
class Node {
private:
- AttributeList attributes_;
Graph &graph_;
Cluster *cluster_ = nullptr;
friend Graph;
- Node(Graph &graph) : graph_(graph)
- {
- }
-
public:
- const AttributeList &attributes() const
- {
- return attributes_;
- }
+ Attributes attributes;
- AttributeList &attributes()
+ Node(Graph &graph) : graph_(graph)
{
- return attributes_;
}
+ public:
void set_parent_cluster(Cluster *cluster);
void set_parent_cluster(Cluster &cluster)
{
this->set_parent_cluster(&cluster);
}
- void set_attribute(StringRef key, StringRef value)
+ Cluster *parent_cluster()
{
- attributes_.set(key, value);
+ return cluster_;
}
void set_shape(Attr_shape shape)
{
- this->set_attribute("shape", shape_to_string(shape));
+ attributes.set("shape", shape_to_string(shape));
}
/* See https://www.graphviz.org/doc/info/attrs.html#k:color. */
void set_background_color(StringRef name)
{
- this->set_attribute("fillcolor", name);
- this->set_attribute("style", "filled");
+ attributes.set("fillcolor", name);
+ attributes.set("style", "filled");
}
void export__as_id(std::stringstream &ss) const;
@@ -208,33 +210,35 @@ class NodePort {
class Edge : blender::NonCopyable, blender::NonMovable {
protected:
- AttributeList attributes_;
NodePort a_;
NodePort b_;
public:
- Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b))
- {
- }
+ Attributes attributes;
- void set_attribute(StringRef key, StringRef value)
+ public:
+ Edge(NodePort a, NodePort b) : a_(std::move(a)), b_(std::move(b))
{
- attributes_.set(key, value);
}
void set_arrowhead(Attr_arrowType type)
{
- this->set_attribute("arrowhead", arrowType_to_string(type));
+ attributes.set("arrowhead", arrowType_to_string(type));
}
void set_arrowtail(Attr_arrowType type)
{
- this->set_attribute("arrowtail", arrowType_to_string(type));
+ attributes.set("arrowtail", arrowType_to_string(type));
}
void set_dir(Attr_dirType type)
{
- this->set_attribute("dir", dirType_to_string(type));
+ attributes.set("dir", dirType_to_string(type));
+ }
+
+ void set_label(StringRef label)
+ {
+ attributes.set("label", label);
}
};
diff --git a/source/blender/blenlib/BLI_float3.hh b/source/blender/blenlib/BLI_float3.hh
index 85575f65365..a976e909738 100644
--- a/source/blender/blenlib/BLI_float3.hh
+++ b/source/blender/blenlib/BLI_float3.hh
@@ -62,11 +62,12 @@ struct float3 {
return {a.x + b.x, a.y + b.y, a.z + b.z};
}
- void operator+=(const float3 &b)
+ float3 &operator+=(const float3 &b)
{
this->x += b.x;
this->y += b.y;
this->z += b.z;
+ return *this;
}
friend float3 operator-(const float3 &a, const float3 &b)
@@ -79,25 +80,28 @@ struct float3 {
return {-a.x, -a.y, -a.z};
}
- void operator-=(const float3 &b)
+ float3 &operator-=(const float3 &b)
{
this->x -= b.x;
this->y -= b.y;
this->z -= b.z;
+ return *this;
}
- void operator*=(float scalar)
+ float3 &operator*=(float scalar)
{
this->x *= scalar;
this->y *= scalar;
this->z *= scalar;
+ return *this;
}
- void operator*=(const float3 &other)
+ float3 &operator*=(const float3 &other)
{
this->x *= other.x;
this->y *= other.y;
this->z *= other.z;
+ return *this;
}
friend float3 operator*(const float3 &a, const float3 &b)
@@ -142,6 +146,17 @@ struct float3 {
return normalize_v3(*this);
}
+ /**
+ * Normalizes the vector in place.
+ */
+ void normalize()
+ {
+ normalize_v3(*this);
+ }
+
+ /**
+ * Returns a normalized vector. The original vector is not changed.
+ */
float3 normalized() const
{
float3 result;
diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh
index a8b939ed32e..85d38149bb9 100644
--- a/source/blender/blenlib/BLI_float4x4.hh
+++ b/source/blender/blenlib/BLI_float4x4.hh
@@ -70,8 +70,8 @@ struct float4x4 {
float4x4 inverted() const
{
- float result[4][4];
- invert_m4_m4(result, values);
+ float4x4 result;
+ invert_m4_m4(result.values, values);
return result;
}
@@ -85,6 +85,18 @@ struct float4x4 {
return this->inverted();
}
+ float4x4 transposed() const
+ {
+ float4x4 result;
+ transpose_m4_m4(result.values, values);
+ return result;
+ }
+
+ float4x4 inverted_transposed_affine() const
+ {
+ return this->inverted_affine().transposed();
+ }
+
struct float3x3_ref {
const float4x4 &data;
diff --git a/source/blender/blenlib/BLI_multi_value_map.hh b/source/blender/blenlib/BLI_multi_value_map.hh
new file mode 100644
index 00000000000..018f080e633
--- /dev/null
+++ b/source/blender/blenlib/BLI_multi_value_map.hh
@@ -0,0 +1,131 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::MultiValueMap<Key, Value>` is an unordered associative container that stores
+ * key-value pairs. It is different from `blender::Map` in that it can store multiple values for
+ * the same key. The list of values that corresponds to a specific key can contain duplicates
+ * and their order is maintained.
+ *
+ * This data structure is different from a `std::multi_map`, because multi_map can store the same
+ * key more than once and MultiValueMap can't.
+ *
+ * Currently, this class exists mainly for convenience. There are no performance benefits over
+ * using Map<Key, Vector<Value>>. In the future, a better implementation for this data structure
+ * can be developed.
+ */
+
+#include "BLI_map.hh"
+#include "BLI_vector.hh"
+
+namespace blender {
+
+template<typename Key, typename Value> class MultiValueMap {
+ private:
+ using MapType = Map<Key, Vector<Value>>;
+ MapType map_;
+
+ public:
+ /**
+ * Add a new value for the given key. If the map contains the key already, the value will be
+ * appended to the list of corresponding values.
+ */
+ void add(const Key &key, const Value &value)
+ {
+ this->add_as(key, value);
+ }
+ void add(const Key &key, Value &&value)
+ {
+ this->add_as(key, std::move(value));
+ }
+ void add(Key &&key, const Value &value)
+ {
+ this->add_as(std::move(key), value);
+ }
+ void add(Key &&key, Value &&value)
+ {
+ this->add_as(std::move(key), std::move(value));
+ }
+ template<typename ForwardKey, typename ForwardValue>
+ void add_as(ForwardKey &&key, ForwardValue &&value)
+ {
+ Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key));
+ vector.append(std::forward<ForwardValue>(value));
+ }
+
+ /**
+ * Add all given values to the key.
+ */
+ void add_multiple(const Key &key, Span<Value> values)
+ {
+ this->add_multiple_as(key, values);
+ }
+ void add_multiple(Key &&key, Span<Value> values)
+ {
+ this->add_multiple_as(std::move(key), values);
+ }
+ template<typename ForwardKey> void add_multiple_as(ForwardKey &&key, Span<Value> values)
+ {
+ Vector<Value> &vector = map_.lookup_or_add_default_as(std::forward<ForwardKey>(key));
+ vector.extend(values);
+ }
+
+ /**
+ * Get a span to all the values that are stored for the given key.
+ */
+ Span<Value> lookup(const Key &key) const
+ {
+ return this->lookup_as(key);
+ }
+ template<typename ForwardKey> Span<Value> lookup_as(const ForwardKey &key) const
+ {
+ const Vector<Value> *vector = map_.lookup_ptr_as(key);
+ if (vector != nullptr) {
+ return vector->as_span();
+ }
+ return {};
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::ItemIterator items() const
+ {
+ return map_.items();
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::KeyIterator keys() const
+ {
+ return map_.keys();
+ }
+
+ /**
+ * Note: This signature will change when the implementation changes.
+ */
+ typename MapType::ValueIterator values() const
+ {
+ return map_.values();
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh
index 72c750d9fa2..b3c9c376141 100644
--- a/source/blender/blenlib/BLI_rand.hh
+++ b/source/blender/blenlib/BLI_rand.hh
@@ -62,6 +62,15 @@ class RandomNumberGenerator {
}
/**
+ * \return Random value (0..N), but never N.
+ */
+ int32_t get_int32(int32_t max_exclusive)
+ {
+ BLI_assert(max_exclusive > 0);
+ return this->get_int32() % max_exclusive;
+ }
+
+ /**
* \return Random value (0..1), but never 1.0.
*/
double get_double()
@@ -77,6 +86,35 @@ class RandomNumberGenerator {
return (float)this->get_int32() / 0x80000000;
}
+ template<typename T> void shuffle(MutableSpan<T> values)
+ {
+ /* Cannot shuffle arrays of this size yet. */
+ BLI_assert(values.size() <= INT32_MAX);
+
+ for (int i = values.size() - 1; i >= 2; i--) {
+ int j = this->get_int32(i);
+ if (i != j) {
+ std::swap(values[i], values[j]);
+ }
+ }
+ }
+
+ /**
+ * Compute uniformly distributed barycentric coordinates.
+ */
+ float3 get_barycentric_coordinates()
+ {
+ float rand1 = this->get_float();
+ float rand2 = this->get_float();
+
+ if (rand1 + rand2 > 1.0f) {
+ rand1 = 1.0f - rand1;
+ rand2 = 1.0f - rand2;
+ }
+
+ return float3(rand1, rand2, 1.0f - rand1 - rand2);
+ }
+
float2 get_unit_float2();
float3 get_unit_float3();
float2 get_triangle_sample(float2 v1, float2 v2, float2 v3);
diff --git a/source/blender/blenlib/BLI_resource_collector.hh b/source/blender/blenlib/BLI_resource_collector.hh
index 9c8fefc1202..20180f3b2c9 100644
--- a/source/blender/blenlib/BLI_resource_collector.hh
+++ b/source/blender/blenlib/BLI_resource_collector.hh
@@ -78,6 +78,12 @@ class ResourceCollector : NonCopyable, NonMovable {
*/
template<typename T> void add(destruct_ptr<T> resource, const char *name)
{
+ /* There is no need to keep track of such types. */
+ if (std::is_trivially_destructible_v<T>) {
+ resource.release();
+ return;
+ }
+
BLI_assert(resource.get() != nullptr);
this->add(
resource.release(),
diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh
index a2de76e080e..5aee0028846 100644
--- a/source/blender/blenlib/BLI_span.hh
+++ b/source/blender/blenlib/BLI_span.hh
@@ -86,7 +86,7 @@ namespace blender {
*/
template<typename T> class Span {
private:
- const T *start_ = nullptr;
+ const T *data_ = nullptr;
int64_t size_ = 0;
public:
@@ -95,13 +95,13 @@ template<typename T> class Span {
*/
Span() = default;
- Span(const T *start, int64_t size) : start_(start), size_(size)
+ Span(const T *start, int64_t size) : data_(start), size_(size)
{
BLI_assert(size >= 0);
}
template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
- Span(const U *start, int64_t size) : start_((const T *)start), size_(size)
+ Span(const U *start, int64_t size) : data_((const T *)start), size_(size)
{
BLI_assert(size >= 0);
}
@@ -135,7 +135,7 @@ template<typename T> class Span {
* Span<Derived *> -> Span<Base *>
*/
template<typename U, typename std::enable_if_t<is_convertible_pointer_v<U, T>> * = nullptr>
- Span(Span<U> array) : start_((T *)array.data()), size_(array.size())
+ Span(Span<U> array) : data_((T *)array.data()), size_(array.size())
{
}
@@ -148,7 +148,7 @@ template<typename T> class Span {
BLI_assert(start >= 0);
BLI_assert(size >= 0);
BLI_assert(start + size <= this->size() || size == 0);
- return Span(start_ + start, size);
+ return Span(data_ + start, size);
}
Span slice(IndexRange range) const
@@ -206,17 +206,17 @@ template<typename T> class Span {
*/
const T *data() const
{
- return start_;
+ return data_;
}
const T *begin() const
{
- return start_;
+ return data_;
}
const T *end() const
{
- return start_ + size_;
+ return data_ + size_;
}
/**
@@ -227,7 +227,7 @@ template<typename T> class Span {
{
BLI_assert(index >= 0);
BLI_assert(index < size_);
- return start_[index];
+ return data_[index];
}
/**
@@ -299,7 +299,7 @@ template<typename T> class Span {
const T &first() const
{
BLI_assert(size_ > 0);
- return start_[0];
+ return data_[0];
}
/**
@@ -309,7 +309,7 @@ template<typename T> class Span {
const T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
}
/**
@@ -319,7 +319,7 @@ template<typename T> class Span {
T get(int64_t index, const T &fallback) const
{
if (index < size_ && index >= 0) {
- return start_[index];
+ return data_[index];
}
return fallback;
}
@@ -335,9 +335,9 @@ template<typename T> class Span {
BLI_assert(size_ < 1000);
for (int64_t i = 0; i < size_; i++) {
- const T &value = start_[i];
+ const T &value = data_[i];
for (int64_t j = i + 1; j < size_; j++) {
- if (value == start_[j]) {
+ if (value == data_[j]) {
return true;
}
}
@@ -357,7 +357,7 @@ template<typename T> class Span {
BLI_assert(size_ < 1000);
for (int64_t i = 0; i < size_; i++) {
- const T &value = start_[i];
+ const T &value = data_[i];
if (other.contains(value)) {
return true;
}
@@ -382,7 +382,7 @@ template<typename T> class Span {
int64_t first_index_try(const T &search_value) const
{
for (int64_t i = 0; i < size_; i++) {
- if (start_[i] == search_value) {
+ if (data_[i] == search_value) {
return i;
}
}
@@ -405,7 +405,7 @@ template<typename T> class Span {
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return Span<NewT>(reinterpret_cast<const NewT *>(start_), new_size);
+ return Span<NewT>(reinterpret_cast<const NewT *>(data_), new_size);
}
/**
@@ -438,13 +438,13 @@ template<typename T> class Span {
*/
template<typename T> class MutableSpan {
private:
- T *start_;
+ T *data_;
int64_t size_;
public:
MutableSpan() = default;
- MutableSpan(T *start, const int64_t size) : start_(start), size_(size)
+ MutableSpan(T *start, const int64_t size) : data_(start), size_(size)
{
}
@@ -458,7 +458,7 @@ template<typename T> class MutableSpan {
operator Span<T>() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
@@ -474,7 +474,7 @@ template<typename T> class MutableSpan {
*/
void fill(const T &value)
{
- initialized_fill_n(start_, size_, value);
+ initialized_fill_n(data_, size_, value);
}
/**
@@ -485,7 +485,7 @@ template<typename T> class MutableSpan {
{
for (int64_t i : indices) {
BLI_assert(i < size_);
- start_[i] = value;
+ data_[i] = value;
}
}
@@ -495,23 +495,23 @@ template<typename T> class MutableSpan {
*/
T *data() const
{
- return start_;
+ return data_;
}
T *begin() const
{
- return start_;
+ return data_;
}
T *end() const
{
- return start_ + size_;
+ return data_ + size_;
}
T &operator[](const int64_t index) const
{
BLI_assert(index < this->size());
- return start_[index];
+ return data_[index];
}
/**
@@ -521,7 +521,7 @@ template<typename T> class MutableSpan {
MutableSpan slice(const int64_t start, const int64_t length) const
{
BLI_assert(start + length <= this->size());
- return MutableSpan(start_ + start, length);
+ return MutableSpan(data_ + start, length);
}
/**
@@ -570,7 +570,7 @@ template<typename T> class MutableSpan {
*/
Span<T> as_span() const
{
- return Span<T>(start_, size_);
+ return Span<T>(data_, size_);
}
/**
@@ -589,7 +589,7 @@ template<typename T> class MutableSpan {
T &last() const
{
BLI_assert(size_ > 0);
- return start_[size_ - 1];
+ return data_[size_ - 1];
}
/**
@@ -608,13 +608,24 @@ template<typename T> class MutableSpan {
}
/**
+ * Copy all values from another span into this span. This invokes undefined behavior when the
+ * destination contains uninitialized data and T is not trivially copy constructible.
+ * The size of both spans is expected to be the same.
+ */
+ void copy_from(Span<T> values)
+ {
+ BLI_assert(size_ == values.size());
+ initialized_copy_n(values.data(), size_, data_);
+ }
+
+ /**
* Returns a new span to the same underlying memory buffer. No conversions are done.
*/
template<typename NewT> MutableSpan<NewT> cast() const
{
BLI_assert((size_ * sizeof(T)) % sizeof(NewT) == 0);
int64_t new_size = size_ * sizeof(T) / sizeof(NewT);
- return MutableSpan<NewT>(reinterpret_cast<NewT *>(start_), new_size);
+ return MutableSpan<NewT>(reinterpret_cast<NewT *>(data_), new_size);
}
};
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index bc35e969e6a..2699f2498ac 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -755,6 +755,43 @@ extern bool BLI_memory_is_zero(const void *arr, const size_t arr_size);
/** \} */
/* -------------------------------------------------------------------- */
+/** \name C++ Macros
+ * \{ */
+
+#ifdef __cplusplus
+
+/* Useful to port C code using enums to C++ where enums are strongly typed.
+ * To use after the enum declaration. */
+# define ENUM_OPERATORS(_enum_type) \
+ inline constexpr _enum_type operator|(_enum_type a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) | b); \
+ } \
+ inline constexpr _enum_type operator&(_enum_type a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) & b); \
+ } \
+ inline constexpr _enum_type operator~(_enum_type a) \
+ { \
+ return a = static_cast<_enum_type>(~static_cast<int>(a)); \
+ } \
+ inline _enum_type &operator|=(_enum_type &a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) | b); \
+ } \
+ inline _enum_type &operator&=(_enum_type &a, _enum_type b) \
+ { \
+ return a = static_cast<_enum_type>(static_cast<int>(a) & b); \
+ }
+
+#else
+/* Output nothing. */
+# define ENUM_OPERATORS(_type)
+#endif
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Misc Macros
* \{ */
diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh
index df577660f4e..52e966267b5 100644
--- a/source/blender/blenlib/BLI_vector.hh
+++ b/source/blender/blenlib/BLI_vector.hh
@@ -560,7 +560,7 @@ class Vector {
/**
* Return a reference to the last element in the vector.
- * This will assert when the vector is empty.
+ * This invokes undefined behavior when the vector is empty.
*/
const T &last() const
{
diff --git a/source/blender/blenlib/BLI_vector_adaptor.hh b/source/blender/blenlib/BLI_vector_adaptor.hh
new file mode 100644
index 00000000000..9c805f242e4
--- /dev/null
+++ b/source/blender/blenlib/BLI_vector_adaptor.hh
@@ -0,0 +1,102 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+/** \file
+ * \ingroup bli
+ *
+ * A `blender::VectorAdaptor` is a container with a fixed maximum size and does not own the
+ * underlying memory. When an adaptor is constructed, you have to provide it with an uninitialized
+ * array that will be filled when elements are added to the vector. The vector adaptor is not able
+ * to grow. Therefore, it is undefined behavior to add more elements than fit into the provided
+ * buffer.
+ */
+
+#include "BLI_span.hh"
+
+namespace blender {
+
+template<typename T> class VectorAdaptor {
+ private:
+ T *begin_;
+ T *end_;
+ T *capacity_end_;
+
+ public:
+ VectorAdaptor() : begin_(nullptr), end_(nullptr), capacity_end_(nullptr)
+ {
+ }
+
+ VectorAdaptor(T *data, int64_t capacity, int64_t size = 0)
+ : begin_(data), end_(data + size), capacity_end_(data + capacity)
+ {
+ }
+
+ VectorAdaptor(MutableSpan<T> span) : VectorAdaptor(span.data(), span.size(), 0)
+ {
+ }
+
+ void append(const T &value)
+ {
+ BLI_assert(end_ < capacity_end_);
+ new (end_) T(value);
+ end_++;
+ }
+
+ void append(T &&value)
+ {
+ BLI_assert(end_ < capacity_end_);
+ new (end_) T(std::move(value));
+ end_++;
+ }
+
+ void append_n_times(const T &value, int64_t n)
+ {
+ BLI_assert(end_ + n <= capacity_end_);
+ uninitialized_fill_n(end_, n, value);
+ end_ += n;
+ }
+
+ void extend(Span<T> values)
+ {
+ BLI_assert(end_ + values.size() <= capacity_end_);
+ uninitialized_copy_n(values.data(), values.size(), end_);
+ end_ += values.size();
+ }
+
+ int64_t capacity() const
+ {
+ return capacity_end_ - begin_;
+ }
+
+ int64_t size() const
+ {
+ return end_ - begin_;
+ }
+
+ bool is_empty() const
+ {
+ return begin_ == end_;
+ }
+
+ bool is_full() const
+ {
+ return end_ == capacity_end_;
+ }
+};
+
+} // namespace blender
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 9703c78e19c..a5af517ecca 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -270,6 +270,7 @@ set(SRC
BLI_utility_mixins.hh
BLI_uvproject.h
BLI_vector.hh
+ BLI_vector_adaptor.hh
BLI_vector_set.hh
BLI_vector_set_slots.hh
BLI_vfontdata.h
@@ -343,3 +344,29 @@ set_source_files_properties(
)
blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ tests/BLI_array_test.cc
+ tests/BLI_disjoint_set_test.cc
+ tests/BLI_edgehash_test.cc
+ tests/BLI_index_mask_test.cc
+ tests/BLI_index_range_test.cc
+ tests/BLI_linear_allocator_test.cc
+ tests/BLI_map_test.cc
+ tests/BLI_math_base_safe_test.cc
+ tests/BLI_memory_utils_test.cc
+ tests/BLI_multi_value_map_test.cc
+ tests/BLI_set_test.cc
+ tests/BLI_span_test.cc
+ tests/BLI_stack_cxx_test.cc
+ tests/BLI_string_ref_test.cc
+ tests/BLI_vector_set_test.cc
+ tests/BLI_vector_test.cc
+ )
+ set(TEST_LIB
+ bf_blenlib
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_bli_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 2b078b3bae5..91aabca7747 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -92,13 +92,9 @@ static bool keycmp(const void *a, const void *b)
if (ka->case_str == 1 || kb->case_str == 1) {
return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
}
- else {
- return (!STREQ(ka->arg, kb->arg));
- }
- }
- else {
- return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
+ return (!STREQ(ka->arg, kb->arg));
}
+ return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
}
static bArgument *lookUp(struct bArgs *ba, const char *arg, int pass, int case_str)
diff --git a/source/blender/blenlib/intern/BLI_dial_2d.c b/source/blender/blenlib/intern/BLI_dial_2d.c
index c6d28e20f35..7363233d573 100644
--- a/source/blender/blenlib/intern/BLI_dial_2d.c
+++ b/source/blender/blenlib/intern/BLI_dial_2d.c
@@ -45,7 +45,7 @@ struct Dial {
bool initialized;
};
-Dial *BLI_dial_initialize(const float start_position[2], float threshold)
+Dial *BLI_dial_init(const float start_position[2], float threshold)
{
Dial *dial = MEM_callocN(sizeof(Dial), "dial");
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 09dbf18acd0..69602cd4209 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -538,10 +538,8 @@ BLI_INLINE bool ghash_insert_safe(GHash *gh,
}
return false;
}
- else {
- ghash_insert_ex(gh, key, val, bucket_index);
- return true;
- }
+ ghash_insert_ex(gh, key, val, bucket_index);
+ return true;
}
BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh,
@@ -564,10 +562,8 @@ BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh,
}
return false;
}
- else {
- ghash_insert_ex_keyonly(gh, key, bucket_index);
- return true;
- }
+ ghash_insert_ex_keyonly(gh, key, bucket_index);
+ return true;
}
/**
@@ -792,9 +788,7 @@ void *BLI_ghash_replace_key(GHash *gh, void *key)
e->e.key = key;
return key_prev;
}
- else {
- return NULL;
- }
+ return NULL;
}
/**
@@ -915,9 +909,7 @@ bool BLI_ghash_remove(GHash *gh,
BLI_mempool_free(gh->entrypool, e);
return true;
}
- else {
- return false;
- }
+ return false;
}
/* same as above but return the value,
@@ -940,9 +932,7 @@ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
BLI_mempool_free(gh->entrypool, e);
return val;
}
- else {
- return NULL;
- }
+ return NULL;
}
/**
@@ -975,10 +965,9 @@ bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val)
BLI_mempool_free(gh->entrypool, e);
return true;
}
- else {
- *r_key = *r_val = NULL;
- return false;
- }
+
+ *r_key = *r_val = NULL;
+ return false;
}
/**
@@ -1246,10 +1235,9 @@ bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key)
BLI_mempool_free(((GHash *)gs)->entrypool, e);
return true;
}
- else {
- *r_key = NULL;
- return false;
- }
+
+ *r_key = NULL;
+ return false;
}
void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve)
@@ -1309,9 +1297,7 @@ void *BLI_gset_pop_key(GSet *gs, const void *key)
BLI_mempool_free(((GHash *)gs)->entrypool, e);
return key_ret;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index a3f93ccc753..f63a523ca60 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -284,28 +284,19 @@ static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
return a[mid];
}
- else {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[hi];
- }
- else {
- return a[lo];
- }
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[hi];
}
+ return a[lo];
}
- else {
- if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[lo];
- }
- else {
- return a[hi];
- }
- }
- else {
- return a[mid];
+
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[lo];
}
+ return a[hi];
}
+ return a[mid];
}
/**
@@ -422,18 +413,12 @@ static char get_largest_axis(const float *bv)
if (middle_point[0] > middle_point[2]) {
return 1; /* max x axis */
}
- else {
- return 5; /* max z axis */
- }
+ return 5; /* max z axis */
}
- else {
- if (middle_point[1] > middle_point[2]) {
- return 3; /* max y axis */
- }
- else {
- return 5; /* max z axis */
- }
+ if (middle_point[1] > middle_point[2]) {
+ return 3; /* max y axis */
}
+ return 5; /* max z axis */
}
/**
@@ -619,13 +604,11 @@ static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, con
if (min_leaf_index <= data->remain_leafs) {
return min_leaf_index;
}
- else if (data->leafs_per_child[depth]) {
+ if (data->leafs_per_child[depth]) {
return data->totleafs -
(data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth];
}
- else {
- return data->remain_leafs;
- }
+ return data->remain_leafs;
}
/**
@@ -1668,10 +1651,8 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node)
data->callback(data->userdata, node->index, data->co, &data->nearest);
return (data->nearest.dist_sq < dist_sq);
}
- else {
- data->nearest.index = node->index;
- return true;
- }
+ data->nearest.index = node->index;
+ return true;
}
}
else {
@@ -1805,9 +1786,7 @@ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *nod
(t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist)) {
return FLT_MAX;
}
- else {
- return max_fff(t1x, t1y, t1z);
- }
+ return max_fff(t1x, t1y, t1z);
}
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
@@ -2354,26 +2333,25 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod
return walk_data->walk_leaf_cb(
(const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata);
}
- else {
- /* First pick the closest node to recurse into */
- if (walk_data->walk_order_cb(
- (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
- for (int i = 0; i != node->totnode; i++) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
- walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
+
+ /* First pick the closest node to recurse into */
+ if (walk_data->walk_order_cb(
+ (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
+ for (int i = 0; i != node->totnode; i++) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
}
}
}
- else {
- for (int i = node->totnode - 1; i >= 0; i--) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
- walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
+ }
+ else {
+ for (int i = node->totnode - 1; i >= 0; i--) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
}
}
}
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index dc5d20ece99..4cac526088b 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -147,7 +147,7 @@ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
lnk_pdst = lnk;
break;
}
- else if (i == curr_index - 1) {
+ if (i == curr_index - 1) {
lnk_psrc = lnk;
}
}
diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c
index 1b9509e36d8..428dd1e2ad8 100644
--- a/source/blender/blenlib/intern/BLI_memiter.c
+++ b/source/blender/blenlib/intern/BLI_memiter.c
@@ -269,9 +269,7 @@ void *BLI_memiter_elem_first(BLI_memiter *mi)
BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
return elem->data;
}
- else {
- return NULL;
- }
+ return NULL;
}
void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
@@ -282,9 +280,7 @@ void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
*r_size = (uint)elem->size;
return elem->data;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
@@ -334,9 +330,7 @@ void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size)
iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
return (void *)data;
}
- else {
- return NULL;
- }
+ return NULL;
}
void *BLI_memiter_iter_step(BLI_memiter_handle *iter)
@@ -352,9 +346,7 @@ void *BLI_memiter_iter_step(BLI_memiter_handle *iter)
iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
return (void *)data;
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c
index 6810601d527..b0c3379ac97 100644
--- a/source/blender/blenlib/intern/DLRB_tree.c
+++ b/source/blender/blenlib/intern/DLRB_tree.c
@@ -299,9 +299,7 @@ static DLRBT_Node *get_grandparent(DLRBT_Node *node)
if (node && node->parent) {
return node->parent->parent;
}
- else {
- return NULL;
- }
+ return NULL;
}
/* get the sibling node (e.g. if node is left child of parent, return right child of parent) */
@@ -311,9 +309,7 @@ static DLRBT_Node *get_sibling(DLRBT_Node *node)
if (node == node->parent->left) {
return node->parent->right;
}
- else {
- return node->parent->left;
- }
+ return node->parent->left;
}
/* sibling not found */
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 85fbe7ece0f..387f9837159 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -355,9 +355,7 @@ static bool bchunk_data_compare(const BChunk *chunk,
if (offset + (size_t)chunk->data_len <= data_base_len) {
return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -893,20 +891,18 @@ static hash_key key_from_chunk_ref(const BArrayInfo *info,
# endif
return key;
}
- else {
- /* corner case - we're too small, calculate the key each time. */
+ /* corner case - we're too small, calculate the key each time. */
- hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
- hash_accum_single(hash_store, hash_store_len, info->accum_steps);
- hash_key key = hash_store[0];
+ hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
+ hash_accum_single(hash_store, hash_store_len, info->accum_steps);
+ hash_key key = hash_store[0];
# ifdef USE_HASH_TABLE_KEY_CACHE
- if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
- key = HASH_TABLE_KEY_FALLBACK;
- }
-# endif
- return key;
+ if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
+ key = HASH_TABLE_KEY_FALLBACK;
}
+# endif
+ return key;
}
static const BChunkRef *table_lookup(const BArrayInfo *info,
@@ -1083,9 +1079,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
if (cref == cref_match_first) {
break;
}
- else {
- cref = cref->next;
- }
+ cref = cref->next;
}
/* happens when bytes are removed from the end of the array */
if (chunk_size_step == data_len_original) {
diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c
index 5dec10a5756..e9ef5e2a927 100644
--- a/source/blender/blenlib/intern/array_utils.c
+++ b/source/blender/blenlib/intern/array_utils.c
@@ -208,7 +208,7 @@ bool _bli_array_iter_span(const void *arr,
if (arr_len == 0) {
return false;
}
- else if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
+ if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
return false;
}
diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c
index 17debb38326..33250105c79 100644
--- a/source/blender/blenlib/intern/bitmap_draw_2d.c
+++ b/source/blender/blenlib/intern/bitmap_draw_2d.c
@@ -316,27 +316,25 @@ static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *
if (co_a[1] < co_b[1]) {
return -1;
}
- else if (co_a[1] > co_b[1]) {
+ if (co_a[1] > co_b[1]) {
return 1;
}
- else if (co_a[0] < co_b[0]) {
+ if (co_a[0] < co_b[0]) {
return -1;
}
- else if (co_a[0] > co_b[0]) {
+ if (co_a[0] > co_b[0]) {
return 1;
}
- else {
- /* co_a & co_b are identical, use the line closest to the x-min */
- const int *co = co_a;
- co_a = verts[a[1]];
- co_b = verts[b[1]];
- int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
- if (ord > 0) {
- return -1;
- }
- if (ord < 0) {
- return 1;
- }
+ /* co_a & co_b are identical, use the line closest to the x-min */
+ const int *co = co_a;
+ co_a = verts[a[1]];
+ co_b = verts[b[1]];
+ int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
+ if (ord > 0) {
+ return -1;
+ }
+ if (ord < 0) {
+ return 1;
}
return 0;
}
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index 83866f766df..5bcb0c0322a 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -216,7 +216,7 @@ static int box_areasort(const void *p1, const void *p2)
if (a1 < a2) {
return 1;
}
- else if (a1 > a2) {
+ if (a1 > a2) {
return -1;
}
return 0;
@@ -246,10 +246,10 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
if (UNLIKELY(v1->free == 0 && v2->free == 0)) {
return 0;
}
- else if (UNLIKELY(v1->free == 0)) {
+ if (UNLIKELY(v1->free == 0)) {
return 1;
}
- else if (UNLIKELY(v2->free == 0)) {
+ if (UNLIKELY(v2->free == 0)) {
return -1;
}
#endif
@@ -266,7 +266,7 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
if (a1 > a2) {
return 1;
}
- else if (a1 < a2) {
+ if (a1 < a2) {
return -1;
}
return 0;
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index b37dc73db29..6e4a8623077 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -115,9 +115,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
break; /* points[i] is a new hull vertex */
}
- else {
- top--; /* pop top point off stack */
- }
+ top--; /* pop top point off stack */
}
r_points[++top] = i; /* push points[i] onto stack */
@@ -141,9 +139,7 @@ int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points
if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
break; /* points[i] is a new hull vertex */
}
- else {
- top--; /* pop top point off stack */
- }
+ top--; /* pop top point off stack */
}
if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
@@ -172,20 +168,17 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
if (a->pt[1] > b->pt[1]) {
return 1;
}
- else if (a->pt[1] < b->pt[1]) {
+ if (a->pt[1] < b->pt[1]) {
return -1;
}
if (a->pt[0] > b->pt[0]) {
return 1;
}
- else if (a->pt[0] < b->pt[0]) {
+ if (a->pt[0] < b->pt[0]) {
return -1;
}
-
- else {
- return 0;
- }
+ return 0;
}
/**
diff --git a/source/blender/blenlib/intern/delaunay_2d.c b/source/blender/blenlib/intern/delaunay_2d.c
index 5f663dcb2e1..28d9ddaef28 100644
--- a/source/blender/blenlib/intern/delaunay_2d.c
+++ b/source/blender/blenlib/intern/delaunay_2d.c
@@ -600,19 +600,19 @@ static int site_lexicographic_cmp(const void *a, const void *b)
if (co1[0] < co2[0]) {
return -1;
}
- else if (co1[0] > co2[0]) {
+ if (co1[0] > co2[0]) {
return 1;
}
- else if (co1[1] < co2[1]) {
+ if (co1[1] < co2[1]) {
return -1;
}
- else if (co1[1] > co2[1]) {
+ if (co1[1] > co2[1]) {
return 1;
}
- else if (s1->orig_index < s2->orig_index) {
+ if (s1->orig_index < s2->orig_index) {
return -1;
}
- else if (s1->orig_index > s2->orig_index) {
+ if (s1->orig_index > s2->orig_index) {
return 1;
}
return 0;
@@ -974,7 +974,7 @@ static void initial_triangulation(CDT_state *cdt)
if (jco[0] > xend) {
break; /* No more j's to process. */
}
- else if (jco[1] > yend) {
+ if (jco[1] > yend) {
/* Get past any string of v's with the same x and too-big y. */
xcur = jco[0];
while (++j < n) {
@@ -1414,7 +1414,7 @@ static bool get_next_crossing_from_vert(CDT_state *cdt,
ok = true;
break;
}
- else if (t->face != cdt->outer_face) {
+ if (t->face != cdt->outer_face) {
orient2 = orient2d(vcur->co, vb->co, v2->co);
#ifdef DEBUG_CDT
if (dbg_level > 1) {
@@ -1683,14 +1683,12 @@ static void add_edge_constraint(
(cd_prev->lambda != 0.0 && cd_prev->in->vert != v && cd_prev->in->next->vert != v)) {
break;
}
- else {
- cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */
+ cd_prev->lambda = -1.0; /* Mark cd_prev as 'deleted'. */
#ifdef DEBUG_CDT
- if (dbg_level > 0) {
- fprintf(stderr, "deleted crossing %d\n", j);
- }
-#endif
+ if (dbg_level > 0) {
+ fprintf(stderr, "deleted crossing %d\n", j);
}
+#endif
}
if (j < i - 1) {
/* Some crossings were deleted. Fix the in and out edges across gap. */
@@ -2002,19 +2000,19 @@ static int evl_cmp(const void *a, const void *b)
if (area->e_id < sb->e_id) {
return -1;
}
- else if (area->e_id > sb->e_id) {
+ if (area->e_id > sb->e_id) {
return 1;
}
- else if (area->lambda < sb->lambda) {
+ if (area->lambda < sb->lambda) {
return -1;
}
- else if (area->lambda > sb->lambda) {
+ if (area->lambda > sb->lambda) {
return 1;
}
- else if (area->v_id < sb->v_id) {
+ if (area->v_id < sb->v_id) {
return -1;
}
- else if (area->v_id > sb->v_id) {
+ if (area->v_id > sb->v_id) {
return 1;
}
return 0;
@@ -2386,9 +2384,7 @@ static const CDT_input *modify_input_for_near_edge_ends(const CDT_input *input,
if (new_input != NULL) {
return (const CDT_input *)new_input;
}
- else {
- return input;
- }
+ return input;
}
static void free_modified_input(CDT_input *input)
@@ -2745,7 +2741,7 @@ static int edge_to_sort_cmp(const void *a, const void *b)
if (e1->len_squared > e2->len_squared) {
return -1;
}
- else if (e1->len_squared < e2->len_squared) {
+ if (e1->len_squared < e2->len_squared) {
return 1;
}
return 0;
@@ -4570,17 +4566,13 @@ static double orient2d(const double *pa, const double *pb, const double *pc)
if (detright <= 0.0) {
return det;
}
- else {
- detsum = detleft + detright;
- }
+ detsum = detleft + detright;
}
else if (detleft < 0.0) {
if (detright >= 0.0) {
return det;
}
- else {
- detsum = -detleft - detright;
- }
+ detsum = -detleft - detright;
}
else {
return det;
@@ -4609,8 +4601,13 @@ static double orient2d(const double *pa, const double *pb, const double *pc)
* returned value has the correct sign. Hence, incircle() is usually quite
* fast, but will run more slowly when the input points are cocircular or
* nearly so.
- */
-
+ *
+ * This function is allowed to be long for two reasons. Firstly, it was taken
+ * from an external source and only slightly adapted, and keeping its original
+ * form will make integration of upstream changes easier. Secondly, it is very
+ * sensitive to floating point errors, and refactoring may break it in subtle
+ * and hard to detect ways.
+ * NOLINTNEXTLINE: readability-function-size */
static double incircleadapt(
const double *pa, const double *pb, const double *pc, const double *pd, double permanent)
{
diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc
index 48b6dc826d0..9ffb1895d04 100644
--- a/source/blender/blenlib/intern/dot_export.cc
+++ b/source/blender/blenlib/intern/dot_export.cc
@@ -28,7 +28,7 @@ Node &Graph::new_node(StringRef label)
Node *node = new Node(*this);
nodes_.append(std::unique_ptr<Node>(node));
top_level_nodes_.add_new(node);
- node->set_attribute("label", label);
+ node->attributes.set("label", label);
return *node;
}
@@ -37,7 +37,7 @@ Cluster &Graph::new_cluster(StringRef label)
Cluster *cluster = new Cluster(*this);
clusters_.append(std::unique_ptr<Cluster>(cluster));
top_level_clusters_.add_new(cluster);
- cluster->set_attribute("label", label);
+ cluster->attributes.set("label", label);
return *cluster;
}
@@ -60,7 +60,7 @@ void Cluster::set_parent_cluster(Cluster *new_parent)
if (parent_ == new_parent) {
return;
}
- else if (parent_ == nullptr) {
+ if (parent_ == nullptr) {
graph_.top_level_clusters_.remove(this);
new_parent->children_.add_new(this);
}
@@ -80,7 +80,7 @@ void Node::set_parent_cluster(Cluster *cluster)
if (cluster_ == cluster) {
return;
}
- else if (cluster_ == nullptr) {
+ if (cluster_ == nullptr) {
graph_.top_level_nodes_.remove(this);
cluster->nodes_.add_new(this);
}
@@ -110,13 +110,25 @@ void Cluster::set_random_cluster_bgcolors()
float hue = rand() / (float)RAND_MAX;
float staturation = 0.3f;
float value = 0.8f;
- this->set_attribute("bgcolor", color_attr_from_hsv(hue, staturation, value));
+ this->attributes.set("bgcolor", color_attr_from_hsv(hue, staturation, value));
for (Cluster *cluster : children_) {
cluster->set_random_cluster_bgcolors();
}
}
+bool Cluster::contains(Node &node) const
+{
+ Cluster *current = node.parent_cluster();
+ while (current != nullptr) {
+ if (current == this) {
+ return true;
+ }
+ current = current->parent_;
+ }
+ return false;
+}
+
/* Dot Generation
**********************************************/
@@ -155,7 +167,7 @@ std::string UndirectedGraph::to_dot_string() const
void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const
{
ss << "graph ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n\n";
for (Node *node : top_level_nodes_) {
@@ -169,10 +181,10 @@ void Graph::export__declare_nodes_and_clusters(std::stringstream &ss) const
void Cluster::export__declare_nodes_and_clusters(std::stringstream &ss) const
{
- ss << "subgraph cluster_" << (uintptr_t)this << " {\n";
+ ss << "subgraph " << this->name() << " {\n";
ss << "graph ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n\n";
for (Node *node : nodes_) {
@@ -192,7 +204,7 @@ void DirectedEdge::export__as_edge_statement(std::stringstream &ss) const
ss << " -> ";
b_.to_dot_string(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
}
void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const
@@ -201,10 +213,10 @@ void UndirectedEdge::export__as_edge_statement(std::stringstream &ss) const
ss << " -- ";
b_.to_dot_string(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
}
-void AttributeList::export__as_bracket_list(std::stringstream &ss) const
+void Attributes::export__as_bracket_list(std::stringstream &ss) const
{
ss << "[";
attributes_.foreach_item([&](StringRef key, StringRef value) {
@@ -228,7 +240,7 @@ void Node::export__as_declaration(std::stringstream &ss) const
{
this->export__as_id(ss);
ss << " ";
- attributes_.export__as_bracket_list(ss);
+ attributes.export__as_bracket_list(ss);
ss << "\n";
}
@@ -296,7 +308,7 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node,
ss << "</table>>";
- node_->set_attribute("label", ss.str());
+ node_->attributes.set("label", ss.str());
node_->set_shape(Attr_shape::Rectangle);
}
diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c
index 9532f78bd44..07aafc1b57b 100644
--- a/source/blender/blenlib/intern/easing.c
+++ b/source/blender/blenlib/intern/easing.c
@@ -72,18 +72,16 @@ float BLI_easing_bounce_ease_out(float time, float begin, float change, float du
if (time < (1 / 2.75f)) {
return change * (7.5625f * time * time) + begin;
}
- else if (time < (2 / 2.75f)) {
+ if (time < (2 / 2.75f)) {
time -= (1.5f / 2.75f);
return change * ((7.5625f * time) * time + 0.75f) + begin;
}
- else if (time < (2.5f / 2.75f)) {
+ if (time < (2.5f / 2.75f)) {
time -= (2.25f / 2.75f);
return change * ((7.5625f * time) * time + 0.9375f) + begin;
}
- else {
- time -= (2.625f / 2.75f);
- return change * ((7.5625f * time) * time + 0.984375f) + begin;
- }
+ time -= (2.625f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.984375f) + begin;
}
float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
@@ -96,10 +94,8 @@ float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float
if (time < duration / 2) {
return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
}
- else {
- return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
- change * 0.5f + begin;
- }
+ return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
+ change * 0.5f + begin;
}
float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
@@ -271,13 +267,12 @@ float BLI_easing_elastic_ease_in_out(
sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
begin;
}
- else {
- time = -time;
- f *= 0.5f;
- return (f * (amplitude * powf(2, 10 * time) *
- sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
- change + begin;
- }
+
+ time = -time;
+ f *= 0.5f;
+ return (f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ change + begin;
}
static const float pow_min = 0.0009765625f; /* = 2^(-10) */
@@ -306,10 +301,8 @@ float BLI_easing_expo_ease_in_out(float time, float begin, float change, float d
if (time <= duration_half) {
return BLI_easing_expo_ease_in(time, begin, change_half, duration_half);
}
- else {
- return BLI_easing_expo_ease_out(
- time - duration_half, begin + change_half, change_half, duration_half);
- }
+ return BLI_easing_expo_ease_out(
+ time - duration_half, begin + change_half, change_half, duration_half);
}
float BLI_easing_linear_ease(float time, float begin, float change, float duration)
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 56529581dd3..05ee02ad869 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -185,7 +185,7 @@ BLI_INLINE EdgeHashEntry *edgehash_insert(EdgeHash *eh, Edge edge, void *value)
if (index == SLOT_EMPTY) {
return edgehash_insert_at_slot(eh, slot, edge, value);
}
- else if (index == SLOT_DUMMY) {
+ if (index == SLOT_DUMMY) {
eh->dummy_count--;
return edgehash_insert_at_slot(eh, slot, edge, value);
}
@@ -200,7 +200,7 @@ BLI_INLINE EdgeHashEntry *edgehash_lookup_entry(EdgeHash *eh, uint v0, uint v1)
if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
return &eh->entries[index];
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return NULL;
}
}
@@ -294,7 +294,7 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value)
eh->entries[index].value = value;
return false;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
if (edgehash_ensure_can_insert(eh)) {
edgehash_insert(eh, edge, value);
}
@@ -360,7 +360,7 @@ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value)
*r_value = &eh->entries[index].value;
return true;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
if (edgehash_ensure_can_insert(eh)) {
*r_value = &edgehash_insert(eh, edge, NULL)->value;
}
@@ -413,7 +413,7 @@ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1)
}
return value;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return NULL;
}
}
@@ -583,7 +583,7 @@ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1)
if (ES_INDEX_HAS_EDGE(es, index, edge)) {
return false;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
edgeset_insert_at_slot(es, slot, edge);
return true;
}
@@ -615,7 +615,7 @@ bool BLI_edgeset_haskey(EdgeSet *es, uint v0, uint v1)
if (ES_INDEX_HAS_EDGE(es, index, edge)) {
return true;
}
- else if (index == SLOT_EMPTY) {
+ if (index == SLOT_EMPTY) {
return false;
}
}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index e61cbd318fc..6c7383bc297 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -980,7 +980,7 @@ static int delete_soft(const char *file, const char **error_message)
"Blender may not support moving files or directories to trash on your system.";
return -1;
}
- else if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
+ if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus)) {
*error_message = process_failed;
return -1;
}
@@ -1036,12 +1036,10 @@ int BLI_delete(const char *file, bool dir, bool recursive)
if (recursive) {
return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
}
- else if (dir) {
+ if (dir) {
return rmdir(file);
}
- else {
- return remove(file);
- }
+ return remove(file);
}
/**
@@ -1184,8 +1182,7 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
- else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode)) {
+ if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
/* copy special type of file */
if (mknod(to, st.st_mode, st.st_rdev)) {
perror("mknod");
@@ -1198,7 +1195,7 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
- else if (!S_ISREG(st.st_mode)) {
+ if (!S_ISREG(st.st_mode)) {
fprintf(stderr, "Copying of this kind of files isn't supported yet\n");
return RecursiveOp_Callback_Error;
}
@@ -1337,7 +1334,7 @@ bool BLI_dir_create_recursive(const char *dirname)
if (BLI_is_dir(dirname)) {
return true;
}
- else if (BLI_exists(dirname)) {
+ if (BLI_exists(dirname)) {
return false;
}
diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c
index a01adf4fa6a..a3b111cf0f2 100644
--- a/source/blender/blenlib/intern/lasso_2d.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -60,10 +60,9 @@ bool BLI_lasso_is_point_inside(const int mcoords[][2],
if (sx == error_value || mcoords_len == 0) {
return false;
}
- else {
- int pt[2] = {sx, sy};
- return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true);
- }
+
+ const int pt[2] = {sx, sy};
+ return isect_point_poly_v2_int(pt, mcoords, mcoords_len, true);
}
/* edge version for lasso select. we assume boundbox check was done */
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 892eca768b3..5e88f8f3e44 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -162,9 +162,8 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink)
BLI_remlink(listbase, vlink);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 651a062e3d5..09bb7ea5711 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -439,9 +439,8 @@ float srgb_to_linearrgb(float c)
if (c < 0.04045f) {
return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
}
- else {
- return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
- }
+
+ return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
}
float linearrgb_to_srgb(float c)
@@ -449,9 +448,8 @@ float linearrgb_to_srgb(float c)
if (c < 0.0031308f) {
return (c < 0.0f) ? 0.0f : c * 12.92f;
}
- else {
- return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
- }
+
+ return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
}
void minmax_rgb(short c[3])
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 7c187679ad1..7717c2f26ff 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -231,9 +231,8 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float
if (c_len > FLT_EPSILON) {
return dot_v3v3(a, b) / c_len;
}
- else {
- return 0.0f;
- }
+
+ return 0.0f;
}
/********************************* Planes **********************************/
@@ -589,9 +588,8 @@ float dist_signed_squared_to_corner_v3v3v3(const float p[3],
if (flip) {
return min_ff(dist_a, dist_b);
}
- else {
- return max_ff(dist_a, dist_b);
- }
+
+ return max_ff(dist_a, dist_b);
}
/**
@@ -1146,9 +1144,8 @@ int isect_line_line_v2_point(
return ISECT_LINE_LINE_CROSS;
}
- else {
- return ISECT_LINE_LINE_COLINEAR;
- }
+
+ return ISECT_LINE_LINE_COLINEAR;
}
/* intersect Line-Line, floats */
@@ -1304,55 +1301,54 @@ int isect_seg_seg_v2_point_ex(const float v0[2],
/* out of segment intersection */
return -1;
}
- else {
- if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
- /* equal lines */
- float s20[2];
- float u_a, u_b;
-
- if (equals_v2v2(v0, v1)) {
- if (len_squared_v2v2(v2, v3) > square_f(eps)) {
- /* use non-point segment as basis */
- SWAP(const float *, v0, v2);
- SWAP(const float *, v1, v3);
-
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s30, v3, v0);
- }
- else { /* both of segments are points */
- if (equals_v2v2(v0, v2)) { /* points are equal */
- copy_v2_v2(r_vi, v0);
- return 1;
- }
- /* two different points */
- return -1;
- }
- }
+ if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
+ /* equal lines */
+ float s20[2];
+ float u_a, u_b;
- sub_v2_v2v2(s20, v2, v0);
+ if (equals_v2v2(v0, v1)) {
+ if (len_squared_v2v2(v2, v3) > square_f(eps)) {
+ /* use non-point segment as basis */
+ SWAP(const float *, v0, v2);
+ SWAP(const float *, v1, v3);
- u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
- u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
-
- if (u_a > u_b) {
- SWAP(float, u_a, u_b);
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s30, v3, v0);
}
+ else { /* both of segments are points */
+ if (equals_v2v2(v0, v2)) { /* points are equal */
+ copy_v2_v2(r_vi, v0);
+ return 1;
+ }
- if (u_a > endpoint_max || u_b < endpoint_min) {
- /* non-overlapping segments */
+ /* two different points */
return -1;
}
- else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
- /* one common point: can return result */
- madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
- return 1;
- }
}
- /* lines are collinear */
- return -1;
+ sub_v2_v2v2(s20, v2, v0);
+
+ u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
+ u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
+
+ if (u_a > u_b) {
+ SWAP(float, u_a, u_b);
+ }
+
+ if (u_a > endpoint_max || u_b < endpoint_min) {
+ /* non-overlapping segments */
+ return -1;
+ }
+ if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
+ /* one common point: can return result */
+ madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
+ return 1;
+ }
}
+
+ /* lines are collinear */
+ return -1;
}
int isect_seg_seg_v2_point(
@@ -1472,13 +1468,13 @@ int isect_line_sphere_v3(const float l1[3],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v3_v3v3fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1490,10 +1486,9 @@ int isect_line_sphere_v3(const float l1[3],
madd_v3_v3v3fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* keep in sync with isect_line_sphere_v3 */
@@ -1520,13 +1515,13 @@ int isect_line_sphere_v2(const float l1[2],
/* no intersections */
return 0;
}
- else if (i == 0.0f) {
+ if (i == 0.0f) {
/* one intersection */
mu = -b / (2.0f * a);
madd_v2_v2v2fl(r_p1, l1, ldir, mu);
return 1;
}
- else if (i > 0.0f) {
+ if (i > 0.0f) {
const float i_sqrt = sqrtf(i); /* avoid calc twice */
/* first intersection */
@@ -1538,10 +1533,9 @@ int isect_line_sphere_v2(const float l1[2],
madd_v2_v2v2fl(r_p2, l1, ldir, mu);
return 2;
}
- else {
- /* math domain error - nan */
- return -1;
- }
+
+ /* math domain error - nan */
+ return -1;
}
/* point in polygon (keep float and int versions in sync) */
@@ -1957,34 +1951,32 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3],
if (UNLIKELY(det == 0.0f || !isfinite(det))) {
return false;
}
- else {
- /* Calculate scaled z-coordinates of vertices and use them to calculate
- * the hit distance.
- */
- const int sign_det = (float_as_int(det) & (int)0x80000000);
- const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
- const float sign_t = xor_fl(t, sign_det);
- if ((sign_t < 0.0f)
- /* Differ from Cycles, don't read r_lambda's original value
- * otherwise we won't match any of the other intersect functions here...
- * which would be confusing. */
+
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const int sign_det = (float_as_int(det) & (int)0x80000000);
+ const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
+ const float sign_t = xor_fl(t, sign_det);
+ if ((sign_t < 0.0f)
+ /* Differ from Cycles, don't read r_lambda's original value
+ * otherwise we won't match any of the other intersect functions here...
+ * which would be confusing. */
#if 0
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
- ) {
- return false;
- }
- else {
- /* Normalize u, v and t. */
- const float inv_det = 1.0f / det;
- if (r_uv) {
- r_uv[0] = u * inv_det;
- r_uv[1] = v * inv_det;
- }
- *r_lambda = t * inv_det;
- return true;
- }
+ ) {
+ return false;
+ }
+
+ /* Normalize u, v and t. */
+ const float inv_det = 1.0f / det;
+ if (r_uv) {
+ r_uv[0] = u * inv_det;
+ r_uv[1] = v * inv_det;
}
+ *r_lambda = t * inv_det;
+ return true;
}
bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3],
@@ -2102,7 +2094,7 @@ bool isect_ray_seg_v2(const float ray_origin[2],
det = cross_v2v2(ray_direction, s10);
if (det != 0.0f) {
const float v = cross_v2v2(v0_local, v1_local);
- float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
+ const float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
const float t = (dot_v2v2(p, ray_direction) / dot_v2v2(ray_direction, ray_direction));
if ((t >= 0.0f) == 0) {
@@ -2215,10 +2207,9 @@ bool isect_line_plane_v3(float r_isect_co[3],
madd_v3_v3v3fl(r_isect_co, l1, u, lambda);
return true;
}
- else {
- /* The segment is parallel to plane */
- return false;
- }
+
+ /* The segment is parallel to plane */
+ return false;
}
/**
@@ -2257,9 +2248,8 @@ bool isect_plane_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -2303,9 +2293,8 @@ bool isect_plane_plane_v3(const float plane_a[4],
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -2436,65 +2425,54 @@ static bool isect_tri_tri_v2_impl_vert(const float t_a0[2],
if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b1, t_a1) <= 0.0f) {
if (line_point_side_v2(t_b2, t_b1, t_a2) <= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
- else if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
+ if (line_point_side_v2(t_a1, t_a2, t_b1) >= 0.0f) {
if (line_point_side_v2(t_b2, t_a2, t_b1) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
- }
- else {
+
return 0;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
@@ -2511,47 +2489,38 @@ static bool isect_tri_tri_v2_impl_edge(const float t_a0[2],
if (line_point_side_v2(t_a0, t_a1, t_b2) >= 0.0f) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
- if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b0) >= 0.0f) {
+ if (line_point_side_v2(t_a2, t_a0, t_b0) >= 0.0f) {
+ return 1;
}
+
+ return 0;
}
+
+ return 0;
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
- if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
- return 1;
- }
- else {
- return 0;
- }
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_b0, t_a2) >= 0.0f) {
+ if (line_point_side_v2(t_a0, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- else {
- return 0;
+
+ if (line_point_side_v2(t_a1, t_a2, t_b2) >= 0.0f) {
+ return 1;
}
- }
- else {
+
return 0;
}
+
+ return 0;
}
+
+ return 0;
}
static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
@@ -2566,32 +2535,26 @@ static int isect_tri_tri_impl_ccw_v2(const float t_a0[2],
if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
return 1;
}
- else {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
- if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
- return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
- }
- }
- else {
- return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
+
+ if (line_point_side_v2(t_b1, t_b2, t_a0) >= 0.0f) {
+ if (line_point_side_v2(t_b2, t_b0, t_a0) >= 0.0f) {
+ return isect_tri_tri_v2_impl_edge(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b1, t_b2, t_b0);
}
+
+ return isect_tri_tri_v2_impl_vert(t_a0, t_a1, t_a2, t_b2, t_b0, t_b1);
}
bool isect_tri_tri_v2(const float t_a0[2],
@@ -2605,18 +2568,15 @@ bool isect_tri_tri_v2(const float t_a0[2],
if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b2, t_b1);
}
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
- }
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a2, t_a1, t_b0, t_b1, t_b2);
}
- else {
- if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
- }
- else {
- return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
- }
+
+ if (line_point_side_v2(t_b0, t_b1, t_b2) < 0.0f) {
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b2, t_b1);
}
+
+ return isect_tri_tri_impl_ccw_v2(t_a0, t_a1, t_a2, t_b0, t_b1, t_b2);
}
/** \} */
@@ -2682,8 +2642,7 @@ int isect_aabb_planes_v3(const float (*planes)[4],
if (plane_point_side_v3(planes[i], bb_far) < 0.0f) {
return ISECT_AABB_PLANE_BEHIND_ANY;
}
- else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) &&
- (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
+ if ((ret != ISECT_AABB_PLANE_CROSS_ANY) && (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
ret = ISECT_AABB_PLANE_CROSS_ANY;
}
}
@@ -2967,7 +2926,7 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 0;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) <= epsilon)) {
+ if (UNLIKELY(fabsf(d) <= epsilon)) {
cross_v3_v3v3(cb, c, b);
mul_v3_fl(a, dot_v3v3(cb, ab) / div);
@@ -2977,34 +2936,33 @@ int isect_line_line_epsilon_v3(const float v1[3],
return 1; /* one intersection only */
}
/* if not */
- else {
- float n[3], t[3];
- float v3t[3], v4t[3];
- sub_v3_v3v3(t, v1, v3);
- /* offset between both plane where the lines lies */
- cross_v3_v3v3(n, a, b);
- project_v3_v3v3(t, t, n);
+ float n[3], t[3];
+ float v3t[3], v4t[3];
+ sub_v3_v3v3(t, v1, v3);
- /* for the first line, offset the second line until it is coplanar */
- add_v3_v3v3(v3t, v3, t);
- add_v3_v3v3(v4t, v4, t);
+ /* offset between both plane where the lines lies */
+ cross_v3_v3v3(n, a, b);
+ project_v3_v3v3(t, t, n);
- sub_v3_v3v3(c, v3t, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4t, v3t);
+ /* for the first line, offset the second line until it is coplanar */
+ add_v3_v3v3(v3t, v3, t);
+ add_v3_v3v3(v4t, v4, t);
- cross_v3_v3v3(ab, a, b);
- cross_v3_v3v3(cb, c, b);
+ sub_v3_v3v3(c, v3t, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4t, v3t);
- mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
- add_v3_v3v3(r_i1, v1, a);
+ cross_v3_v3v3(ab, a, b);
+ cross_v3_v3v3(cb, c, b);
- /* for the second line, just subtract the offset from the first intersection point */
- sub_v3_v3v3(r_i2, r_i1, t);
+ mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
+ add_v3_v3v3(r_i1, v1, a);
- return 2; /* two nearest points */
- }
+ /* for the second line, just subtract the offset from the first intersection point */
+ sub_v3_v3v3(r_i2, r_i1, t);
+
+ return 2; /* two nearest points */
}
int isect_line_line_v3(const float v1[3],
@@ -3047,31 +3005,29 @@ bool isect_line_line_strict_v3(const float v1[3],
return false;
}
/* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) < epsilon)) {
+ if (UNLIKELY(fabsf(d) < epsilon)) {
return false;
}
- else {
- float f1, f2;
- cross_v3_v3v3(cb, c, b);
- cross_v3_v3v3(ca, c, a);
- f1 = dot_v3v3(cb, ab) / div;
- f2 = dot_v3v3(ca, ab) / div;
+ float f1, f2;
+ cross_v3_v3v3(cb, c, b);
+ cross_v3_v3v3(ca, c, a);
- if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
- mul_v3_fl(a, f1);
- add_v3_v3v3(vi, v1, a);
+ f1 = dot_v3v3(cb, ab) / div;
+ f2 = dot_v3v3(ca, ab) / div;
- if (r_lambda) {
- *r_lambda = f1;
- }
+ if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
+ mul_v3_fl(a, f1);
+ add_v3_v3v3(vi, v1, a);
- return true; /* intersection found */
- }
- else {
- return false;
+ if (r_lambda) {
+ *r_lambda = f1;
}
+
+ return true; /* intersection found */
}
+
+ return false;
}
/**
@@ -3237,15 +3193,14 @@ bool isect_ray_aabb_v3_simple(const float orig[3],
if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
return false;
}
- else {
- if (tmin) {
- *tmin = hit_dist[0];
- }
- if (tmax) {
- *tmax = hit_dist[1];
- }
- return true;
+
+ if (tmin) {
+ *tmin = hit_dist[0];
+ }
+ if (tmax) {
+ *tmax = hit_dist[1];
}
+ return true;
}
float closest_to_ray_v3(float r_close[3],
@@ -3463,7 +3418,7 @@ static bool point_in_slice(const float p[3],
/* adult sister defining the slice planes by the origin and the normal
* NOTE |normal| may not be 1 but defining the thickness of the slice */
-static bool point_in_slice_as(float p[3], float origin[3], float normal[3])
+static bool point_in_slice_as(const float p[3], const float origin[3], const float normal[3])
{
float h, rp[3];
sub_v3_v3v3(rp, p, origin);
@@ -3522,9 +3477,8 @@ bool isect_point_tri_v3(
return true;
}
- else {
- return false;
- }
+
+ return false;
}
bool clip_segment_v3_plane(
@@ -3547,7 +3501,7 @@ bool clip_segment_v3_plane(
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p2, p2);
madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div);
@@ -3559,7 +3513,7 @@ bool clip_segment_v3_plane(
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
const float p1_copy[3] = {UNPACK3(p1)};
copy_v3_v3(r_p1, p1);
madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div);
@@ -3598,7 +3552,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= div) {
return false;
}
- else if (t > 0.0f) {
+ if (t > 0.0f) {
t /= div;
if (t > p1_fac) {
p1_fac = t;
@@ -3613,7 +3567,7 @@ bool clip_segment_v3_plane_n(const float p1[3],
if (t >= 0.0f) {
return false;
}
- else if (t > div) {
+ if (t > div) {
t /= div;
if (t < p2_fac) {
p2_fac = t;
@@ -3797,8 +3751,8 @@ int barycentric_inside_triangle_v2(const float w[3])
if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
return 1;
}
- else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
- IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
+ if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
+ IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
return 2;
}
@@ -4095,68 +4049,67 @@ int interp_sparse_array(float *array, const int list_size, const float skipval)
if (found_valid == 0) {
return -1;
}
- else if (found_invalid == 0) {
+ if (found_invalid == 0) {
return 0;
}
- else {
- /* found invalid depths, interpolate */
- float valid_last = skipval;
- int valid_ofs = 0;
- float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ /* found invalid depths, interpolate */
+ float valid_last = skipval;
+ int valid_ofs = 0;
- int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
- int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+ float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- array_up[i] = valid_last;
- ofs_tot_up[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
+ int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ array_up[i] = valid_last;
+ ofs_tot_up[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
}
+ }
- valid_last = skipval;
- valid_ofs = 0;
+ valid_last = skipval;
+ valid_ofs = 0;
- for (i = list_size - 1; i >= 0; i--) {
- if (array[i] == skipval) {
- array_down[i] = valid_last;
- ofs_tot_down[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
+ for (i = list_size - 1; i >= 0; i--) {
+ if (array[i] == skipval) {
+ array_down[i] = valid_last;
+ ofs_tot_down[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
}
+ }
- /* now blend */
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- if (array_up[i] != skipval && array_down[i] != skipval) {
- array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
- (array_down[i] * (float)ofs_tot_up[i])) /
- (float)(ofs_tot_down[i] + ofs_tot_up[i]);
- }
- else if (array_up[i] != skipval) {
- array[i] = array_up[i];
- }
- else if (array_down[i] != skipval) {
- array[i] = array_down[i];
- }
+ /* now blend */
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ if (array_up[i] != skipval && array_down[i] != skipval) {
+ array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
+ (array_down[i] * (float)ofs_tot_up[i])) /
+ (float)(ofs_tot_down[i] + ofs_tot_up[i]);
+ }
+ else if (array_up[i] != skipval) {
+ array[i] = array_up[i];
+ }
+ else if (array_down[i] != skipval) {
+ array[i] = array_down[i];
}
}
+ }
- MEM_freeN(array_up);
- MEM_freeN(array_down);
+ MEM_freeN(array_up);
+ MEM_freeN(array_down);
- MEM_freeN(ofs_tot_up);
- MEM_freeN(ofs_tot_down);
- }
+ MEM_freeN(ofs_tot_up);
+ MEM_freeN(ofs_tot_down);
return 1;
}
@@ -4279,7 +4232,7 @@ void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
@@ -4364,7 +4317,7 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
ix_flag = IS_POINT_IX;
break;
}
- else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
+ if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
ix_flag = IS_SEGMENT_IX;
break;
}
@@ -4647,17 +4600,15 @@ float resolve_quad_u_v2(const float st[2],
if (IS_ZERO(fDen) == 0) {
return (float)(a / fDen);
}
- else {
- return 0.0f;
- }
- }
- else {
- const double desc_sq = b * b - a * fC;
- const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
- const double s = signed_area > 0 ? (-1.0) : 1.0;
- return (float)(((a - b) + s * desc) / denom);
+ return 0.0f;
}
+
+ const double desc_sq = b * b - a * fC;
+ const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
+ const double s = signed_area > 0 ? (-1.0) : 1.0;
+
+ return (float)(((a - b) + s * desc) / denom);
}
#undef IS_ZERO
@@ -4959,7 +4910,7 @@ void projmat_from_subregion(const float projmat[4][4],
}
}
-static void i_multmatrix(float icand[4][4], float Vm[4][4])
+static void i_multmatrix(const float icand[4][4], float Vm[4][4])
{
int row, col;
float temp[4][4];
@@ -5155,7 +5106,7 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3])
{
- float target[3] = {0.0f, 0.0f, 1.0f};
+ const float target[3] = {0.0f, 0.0f, 1.0f};
float axis[3];
cross_v3_v3v3(axis, no, target);
@@ -6139,17 +6090,16 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
/* no angle difference (use fallback, length wont make any difference) */
return (1.0f / 3.0f) * 0.75f;
}
- else if (tan_dot < -1.0f + eps) {
+ if (tan_dot < -1.0f + eps) {
/* parallele tangents (half-circle) */
return (1.0f / 2.0f);
}
- else {
- /* non-aligned tangents, calculate handle length */
- const float angle = acosf(tan_dot) / 2.0f;
- /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
- const float angle_sin = sinf(angle);
- const float angle_cos = cosf(angle);
- return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
- }
+ /* non-aligned tangents, calculate handle length */
+ const float angle = acosf(tan_dot) / 2.0f;
+
+ /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
+ const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
}
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index 6277b1cd9dc..13a1816f1bd 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -286,7 +286,7 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
if (float_output) {
const float *row1, *row2, *row3, *row4;
- float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* pixel value must be already wrapped, however values at boundaries may flip */
if (wrap_x) {
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index a2f7cc24dd3..a6368981050 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -644,9 +644,8 @@ float angle_signed_normalized_qt(const float q[4])
if (q[0] >= 0.0f) {
return 2.0f * saacos(q[0]);
}
- else {
- return -2.0f * saacos(-q[0]);
- }
+
+ return -2.0f * saacos(-q[0]);
}
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
@@ -654,11 +653,10 @@ float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_normalized_qtqt(q1, q2);
}
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_normalized_qtqt(q1, q2_copy);
- }
+
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_normalized_qtqt(q1, q2_copy);
}
float angle_signed_qt(const float q[4])
@@ -675,11 +673,10 @@ float angle_signed_qtqt(const float q1[4], const float q2[4])
if (dot_qtqt(q1, q2) >= 0.0f) {
return angle_qtqt(q1, q2);
}
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_qtqt(q1, q2_copy);
- }
+
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_qtqt(q1, q2_copy);
}
/** \} */
@@ -1594,12 +1591,11 @@ static const RotOrderInfo *get_rotation_order_info(const short order)
if (order < 1) {
return &rotOrders[0];
}
- else if (order < 6) {
+ if (order < 6) {
return &rotOrders[order - 1];
}
- else {
- return &rotOrders[5];
- }
+
+ return &rotOrders[5];
}
/* Construct quaternion from Euler angles (in radians). */
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 7f1840228e2..909d508e262 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -506,11 +506,10 @@ float angle_normalized_v3v3(const float v1[3], const float v2[3])
if (dot_v3v3(v1, v2) >= 0.0f) {
return 2.0f * saasin(len_v3v3(v1, v2) / 2.0f);
}
- else {
- float v2_n[3];
- negate_v3_v3(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
- }
+
+ float v2_n[3];
+ negate_v3_v3(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
}
float angle_normalized_v2v2(const float v1[2], const float v2[2])
@@ -523,11 +522,10 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2])
if (dot_v2v2(v1, v2) >= 0.0f) {
return 2.0f * saasin(len_v2v2(v1, v2) / 2.0f);
}
- else {
- float v2_n[2];
- negate_v2_v2(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
- }
+
+ float v2_n[2];
+ negate_v2_v2(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
}
/**
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index d912cb8d464..67d41ffb779 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -427,9 +427,8 @@ static int BLI_path_unc_prefix_len(const char *path)
/* we assume long UNC path like \\?\server\share\folder etc... */
return 4;
}
- else {
- return 2;
- }
+
+ return 2;
}
return 0;
@@ -683,7 +682,7 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
has_extension = true;
break;
}
- else if (ELEM(string[a], '/', '\\')) {
+ if (ELEM(string[a], '/', '\\')) {
break;
}
}
@@ -713,9 +712,8 @@ bool BLI_path_parent_dir(char *path)
strcpy(path, tmp); /* We assume pardir is always shorter... */
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -764,11 +762,10 @@ static bool stringframe_chars(const char *path, int *char_start, int *char_end)
*char_end = ch_end;
return true;
}
- else {
- *char_start = -1;
- *char_end = -1;
- return false;
- }
+
+ *char_start = -1;
+ *char_end = -1;
+ return false;
}
/**
@@ -1731,9 +1728,8 @@ void BLI_join_dirfile(char *__restrict dst,
dst[dirlen - 1] = '\0';
return; /* dir fills the path */
}
- else {
- memcpy(dst, dir, dirlen + 1);
- }
+
+ memcpy(dst, dir, dirlen + 1);
if (dirlen + 1 >= maxlen) {
return; /* fills the path */
@@ -1891,32 +1887,31 @@ bool BLI_path_name_at_index(const char *__restrict path,
}
return false;
}
- else {
- /* negative number, reverse where -1 is the last element */
- int index_step = -1;
- int prev = strlen(path);
- int i = prev - 1;
- while (true) {
- const char c = i >= 0 ? path[i] : '\0';
- if (ELEM(c, SEP, ALTSEP, '\0')) {
- if (prev - 1 != i) {
- i += 1;
- if (index_step == index) {
- *r_offset = i;
- *r_len = prev - i;
- return true;
- }
- index_step -= 1;
- }
- if (c == '\0') {
- break;
+
+ /* negative number, reverse where -1 is the last element */
+ int index_step = -1;
+ int prev = strlen(path);
+ int i = prev - 1;
+ while (true) {
+ const char c = i >= 0 ? path[i] : '\0';
+ if (ELEM(c, SEP, ALTSEP, '\0')) {
+ if (prev - 1 != i) {
+ i += 1;
+ if (index_step == index) {
+ *r_offset = i;
+ *r_len = prev - i;
+ return true;
}
- prev = i;
+ index_step -= 1;
}
- i -= 1;
+ if (c == '\0') {
+ break;
+ }
+ prev = i;
}
- return false;
+ i -= 1;
}
+ return false;
}
/**
@@ -1930,7 +1925,7 @@ const char *BLI_path_slash_find(const char *string)
if (!ffslash) {
return fbslash;
}
- else if (!fbslash) {
+ if (!fbslash) {
return ffslash;
}
@@ -1948,7 +1943,7 @@ const char *BLI_path_slash_rfind(const char *string)
if (!lfslash) {
return lbslash;
}
- else if (!lbslash) {
+ if (!lbslash) {
return lfslash;
}
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index 90a4a4f4c2d..d1e2bd58909 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -177,12 +177,11 @@ BLI_INLINE eSign signum_enum(float a)
if (UNLIKELY(a == 0.0f)) {
return 0;
}
- else if (a > 0.0f) {
+ if (a > 0.0f) {
return 1;
}
- else {
- return -1;
- }
+
+ return -1;
}
/**
@@ -250,7 +249,7 @@ static uint kdtree2d_balance_recursive(
if (totnode <= 0) {
return KDNODE_UNSET;
}
- else if (totnode == 1) {
+ if (totnode == 1) {
return 0 + ofs;
}
@@ -330,9 +329,8 @@ static void kdtree2d_node_remove(struct KDTree2D *tree, uint index)
if (node_index == KDNODE_UNSET) {
return;
}
- else {
- tree->nodes_map[index] = KDNODE_UNSET;
- }
+
+ tree->nodes_map[index] = KDNODE_UNSET;
node = &tree->nodes[node_index];
tree->totnode -= 1;
diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c
index 41364c5a3a9..7bfca149ffb 100644
--- a/source/blender/blenlib/intern/polyfill_2d_beautify.c
+++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c
@@ -64,14 +64,14 @@ static int oedge_cmp(const void *a1, const void *a2)
if (x1->verts[0] > x2->verts[0]) {
return 1;
}
- else if (x1->verts[0] < x2->verts[0]) {
+ if (x1->verts[0] < x2->verts[0]) {
return -1;
}
if (x1->verts[1] > x2->verts[1]) {
return 1;
}
- else if (x1->verts[1] < x2->verts[1]) {
+ if (x1->verts[1] < x2->verts[1]) {
return -1;
}
@@ -79,7 +79,7 @@ static int oedge_cmp(const void *a1, const void *a2)
if (x1->e_half > x2->e_half) {
return 1;
}
- else if (x1->e_half < x2->e_half) {
+ if (x1->e_half < x2->e_half) {
return -1;
}
/* Should never get here, no two edges should be the same. */
@@ -141,7 +141,7 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
break;
}
- else if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
+ if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
break;
}
@@ -150,11 +150,10 @@ float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
if (lock_degenerate) {
break;
}
- else {
- return -FLT_MAX; /* always rotate */
- }
+
+ return -FLT_MAX; /* always rotate */
}
- else if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
+ if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
return -FLT_MAX; /* always rotate */
}
diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c
index 3ad1844cfe1..ac522171951 100644
--- a/source/blender/blenlib/intern/quadric.c
+++ b/source/blender/blenlib/intern/quadric.c
@@ -107,9 +107,8 @@ static bool quadric_to_tensor_m3_inverse(const Quadric *q, double m[3][3], doubl
return true;
}
- else {
- return false;
- }
+
+ return false;
}
void BLI_quadric_to_vector_v3(const Quadric *q, double v[3])
@@ -161,7 +160,6 @@ bool BLI_quadric_optimize(const Quadric *q, double v[3], const double epsilon)
negate_v3_db(v);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index bf3c8730b01..f952b62cb61 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -238,15 +238,14 @@ static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], c
if (div == 0.0) {
return 1; /* co-linear */
}
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
- (v1[0] - v3[0]) * (v4[1] - v3[1])) /
- div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
- (v1[0] - v3[0]) * (v2[1] - v1[1])) /
- div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
+
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
static int isect_segments_fl(const float v1[2],
const float v2[2],
@@ -258,15 +257,14 @@ static int isect_segments_fl(const float v1[2],
if (div == 0.0) {
return 1; /* co-linear */
}
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
- (v1[0] - v3[0]) * (v4[1] - v3[1])) /
- div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
- (v1[0] - v3[0]) * (v2[1] - v1[1])) /
- div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
+
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
}
bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
@@ -289,31 +287,30 @@ bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
return true;
}
- else {
- /* both points are outside but may intersect the rect */
- int tvec1[2];
- int tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
- tvec2[1] = rect->ymax;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
- /* diagonal: [\] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax;
- tvec2[1] = rect->ymin;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
+ /* both points are outside but may intersect the rect */
+ int tvec1[2];
+ int tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
- /* no intersection */
- return false;
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
}
+
+ /* no intersection */
+ return false;
}
bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
@@ -336,31 +333,30 @@ bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[
if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
return true;
}
- else {
- /* both points are outside but may intersect the rect */
- float tvec1[2];
- float tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin;
- tvec2[1] = rect->ymax;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
- /* diagonal: [\] */
- tvec1[0] = rect->xmin;
- tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax;
- tvec2[1] = rect->ymin;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
+ /* both points are outside but may intersect the rect */
+ float tvec1[2];
+ float tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
- /* no intersection */
- return false;
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
}
+
+ /* no intersection */
+ return false;
}
bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
@@ -890,15 +886,14 @@ bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
}
return true;
}
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
+
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
}
+ return false;
}
bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
@@ -920,15 +915,14 @@ bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
}
return true;
}
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
+
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
}
+ return false;
}
bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
@@ -943,13 +937,12 @@ bool BLI_rctf_isect_rect_x(const rctf *src1, const rctf *src2, float range_x[2])
}
return true;
}
- else {
- if (range_x) {
- range_x[0] = 0;
- range_x[1] = 0;
- }
- return false;
+
+ if (range_x) {
+ range_x[0] = 0;
+ range_x[1] = 0;
}
+ return false;
}
bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
@@ -964,13 +957,12 @@ bool BLI_rctf_isect_rect_y(const rctf *src1, const rctf *src2, float range_y[2])
}
return true;
}
- else {
- if (range_y) {
- range_y[0] = 0;
- range_y[1] = 0;
- }
- return false;
+
+ if (range_y) {
+ range_y[0] = 0;
+ range_y[1] = 0;
}
+ return false;
}
bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
@@ -985,13 +977,12 @@ bool BLI_rcti_isect_rect_x(const rcti *src1, const rcti *src2, int range_x[2])
}
return true;
}
- else {
- if (range_x) {
- range_x[0] = 0;
- range_x[1] = 0;
- }
- return false;
+
+ if (range_x) {
+ range_x[0] = 0;
+ range_x[1] = 0;
}
+ return false;
}
bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
@@ -1006,13 +997,12 @@ bool BLI_rcti_isect_rect_y(const rcti *src1, const rcti *src2, int range_y[2])
}
return true;
}
- else {
- if (range_y) {
- range_y[0] = 0;
- range_y[1] = 0;
- }
- return false;
+
+ if (range_y) {
+ range_y[0] = 0;
+ range_y[1] = 0;
}
+ return false;
}
void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 4723a3532ac..8b536354af2 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -91,13 +91,13 @@ static int vergscdata(const void *a1, const void *a2)
if (x1->vert->xy[1] < x2->vert->xy[1]) {
return 1;
}
- else if (x1->vert->xy[1] > x2->vert->xy[1]) {
+ if (x1->vert->xy[1] > x2->vert->xy[1]) {
return -1;
}
- else if (x1->vert->xy[0] > x2->vert->xy[0]) {
+ if (x1->vert->xy[0] > x2->vert->xy[0]) {
return 1;
}
- else if (x1->vert->xy[0] < x2->vert->xy[0]) {
+ if (x1->vert->xy[0] < x2->vert->xy[0]) {
return -1;
}
@@ -111,13 +111,13 @@ static int vergpoly(const void *a1, const void *a2)
if (x1->min_xy[0] > x2->min_xy[0]) {
return 1;
}
- else if (x1->min_xy[0] < x2->min_xy[0]) {
+ if (x1->min_xy[0] < x2->min_xy[0]) {
return -1;
}
- else if (x1->min_xy[1] > x2->min_xy[1]) {
+ if (x1->min_xy[1] > x2->min_xy[1]) {
return 1;
}
- else if (x1->min_xy[1] < x2->min_xy[1]) {
+ if (x1->min_xy[1] < x2->min_xy[1]) {
return -1;
}
@@ -259,7 +259,7 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2]
if (inp < 0.0f) {
return false;
}
- else if (inp == 0.0f) {
+ if (inp == 0.0f) {
if (v1[0] == v3[0] && v1[1] == v3[1]) {
return false;
}
@@ -417,25 +417,24 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
eve->edge_tot = 0;
break;
}
- else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
+ if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
ed1->v2 = eed->v2;
eed->v2->edge_tot++;
eve->edge_tot = 0;
break;
}
- else {
- if (boundinsideEV(eed, eve)) {
- const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
- if (dist < SF_EPSILON_SQ) {
- /* new edge */
- ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
-
- /* printf("fill: vertex near edge %x\n", eve); */
- ed1->poly_nr = eed->poly_nr;
- eed->v1 = eve;
- eve->edge_tot = 3;
- break;
- }
+
+ if (boundinsideEV(eed, eve)) {
+ const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
+ if (dist < SF_EPSILON_SQ) {
+ /* new edge */
+ ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
+
+ /* printf("fill: vertex near edge %x\n", eve); */
+ ed1->poly_nr = eed->poly_nr;
+ eed->v1 = eve;
+ eve->edge_tot = 3;
+ break;
}
}
}
@@ -875,41 +874,40 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
if (UNLIKELY(eve == NULL)) {
return 0;
}
+
+ float n[3];
+
+ if (nor_proj) {
+ copy_v3_v3(n, nor_proj);
+ }
else {
- float n[3];
+ /* define projection: with 'best' normal */
+ /* Newell's Method */
+ /* Similar code used elsewhere, but this checks for double ups
+ * which historically this function supports so better not change */
- if (nor_proj) {
- copy_v3_v3(n, nor_proj);
- }
- else {
- /* define projection: with 'best' normal */
- /* Newell's Method */
- /* Similar code used elsewhere, but this checks for double ups
- * which historically this function supports so better not change */
-
- /* warning: this only gives stable direction with single polygons,
- * ideally we'd calculate connectivity and each polys normal, see T41047 */
- const float *v_prev;
-
- zero_v3(n);
- eve = sf_ctx->fillvertbase.last;
- v_prev = eve->co;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
- add_newell_cross_v3_v3v3(n, v_prev, eve->co);
- v_prev = eve->co;
- }
- }
- }
+ /* warning: this only gives stable direction with single polygons,
+ * ideally we'd calculate connectivity and each polys normal, see T41047 */
+ const float *v_prev;
- if (UNLIKELY(normalize_v3(n) == 0.0f)) {
- return 0;
+ zero_v3(n);
+ eve = sf_ctx->fillvertbase.last;
+ v_prev = eve->co;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
+ add_newell_cross_v3_v3v3(n, v_prev, eve->co);
+ v_prev = eve->co;
+ }
}
+ }
- axis_dominant_v3_to_m3_negate(mat_2d, n);
+ if (UNLIKELY(normalize_v3(n) == 0.0f)) {
+ return 0;
}
+ axis_dominant_v3_to_m3_negate(mat_2d, n);
+
/* STEP 1: COUNT POLYS */
if (sf_ctx->poly_nr != SF_POLY_UNSET) {
poly = (unsigned short)(sf_ctx->poly_nr + 1);
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 31b2bf85142..660d3dca807 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -139,9 +139,8 @@ static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void
if (a > b) {
return -1;
}
- else {
- return (a < b);
- }
+
+ return (a < b);
}
static ScanFillEdge *edge_step(PolyInfo *poly_info,
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 6d1ce3c84cd..ab2b0fd2928 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -253,10 +253,9 @@ bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item)
e->val = item;
return false;
}
- else {
- BLI_smallhash_insert(sh, key, item);
- return true;
- }
+
+ BLI_smallhash_insert(sh, key, item);
+ return true;
}
#ifdef USE_REMOVE
diff --git a/source/blender/blenlib/intern/sort_utils.c b/source/blender/blenlib/intern/sort_utils.c
index 09babd3d424..e02d77de0c7 100644
--- a/source/blender/blenlib/intern/sort_utils.c
+++ b/source/blender/blenlib/intern/sort_utils.c
@@ -44,12 +44,11 @@ int BLI_sortutil_cmp_float(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
@@ -59,12 +58,11 @@ int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_int(const void *a_, const void *b_)
@@ -74,12 +72,11 @@ int BLI_sortutil_cmp_int(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
@@ -89,12 +86,11 @@ int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_ptr(const void *a_, const void *b_)
@@ -104,12 +100,11 @@ int BLI_sortutil_cmp_ptr(const void *a_, const void *b_)
if (a->sort_value > b->sort_value) {
return 1;
}
- else if (a->sort_value < b->sort_value) {
+ if (a->sort_value < b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_)
@@ -119,10 +114,9 @@ int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_)
if (a->sort_value < b->sort_value) {
return 1;
}
- else if (a->sort_value > b->sort_value) {
+ if (a->sort_value > b->sort_value) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index d3191148c90..fbd9e562b6a 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -96,9 +96,7 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
memcpy(dir, pwd, srclen + 1);
return dir;
}
- else {
- return NULL;
- }
+ return NULL;
}
return getcwd(dir, maxncpy);
#endif
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index abdae06acd5..8b4720ca1e1 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -394,9 +394,7 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
if (LIKELY(*(endMatch - 1) != '\\')) {
break;
}
- else {
- endMatch++;
- }
+ endMatch++;
}
if (endMatch) {
@@ -470,11 +468,9 @@ char *BLI_str_replaceN(const char *__restrict str,
return str_new;
}
- else {
- /* Just create a new copy of the entire string - we avoid going through the assembly buffer
- * for what should be a bit more efficiency. */
- return BLI_strdup(str);
- }
+ /* Just create a new copy of the entire string - we avoid going through the assembly buffer
+ * for what should be a bit more efficiency. */
+ return BLI_strdup(str);
}
/**
@@ -574,10 +570,10 @@ int BLI_strcasecmp(const char *s1, const char *s2)
if (c1 < c2) {
return -1;
}
- else if (c1 > c2) {
+ if (c1 > c2) {
return 1;
}
- else if (c1 == 0) {
+ if (c1 == 0) {
break;
}
}
@@ -597,10 +593,10 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len)
if (c1 < c2) {
return -1;
}
- else if (c1 > c2) {
+ if (c1 > c2) {
return 1;
}
- else if (c1 == 0) {
+ if (c1 == 0) {
break;
}
}
@@ -627,15 +623,13 @@ static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker)
if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit))) {
continue;
}
- else if (isdigit(*(p1 + numdigit))) {
+ if (isdigit(*(p1 + numdigit))) {
return 1; /* s2 is bigger */
}
- else if (isdigit(*(p2 + numdigit))) {
+ if (isdigit(*(p2 + numdigit))) {
return -1; /* s1 is bigger */
}
- else {
- break;
- }
+ break;
}
/* same number of digits, compare size of number */
@@ -759,14 +753,14 @@ int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
if (str1_len == str2_len) {
return strncmp(str1, str2, str2_len);
}
- else if (str1_len > str2_len) {
+ if (str1_len > str2_len) {
int ret = strncmp(str1, str2, str2_len);
if (ret == 0) {
ret = 1;
}
return ret;
}
- else {
+ {
int ret = strncmp(str1, str2, str1_len);
if (ret == 0) {
ret = -1;
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index e9fdce83710..0a723a623f0 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -215,11 +215,9 @@ int BLI_utf8_invalid_strip(char *str, size_t length)
tot++;
break;
}
- else {
- /* strip, keep looking */
- memmove(str, str + 1, length + 1); /* +1 for NULL char! */
- tot++;
- }
+ /* strip, keep looking */
+ memmove(str, str + 1, length + 1); /* +1 for NULL char! */
+ tot++;
}
return tot;
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index fb9530b5cb5..dbeb75570fb 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -72,7 +72,7 @@ size_t BLI_split_name_num(char *left, int *nr, const char *name, const char deli
}
return a;
}
- else if (isdigit(name[a]) == 0) {
+ if (isdigit(name[a]) == 0) {
/* non-numeric suffix - give up */
break;
}
diff --git a/source/blender/blenlib/intern/threads.cc b/source/blender/blenlib/intern/threads.cc
index a8333d0c696..002b78bec39 100644
--- a/source/blender/blenlib/intern/threads.cc
+++ b/source/blender/blenlib/intern/threads.cc
@@ -309,7 +309,7 @@ int BLI_system_thread_count(void)
if (num_threads_override != 0) {
return num_threads_override;
}
- else if (LIKELY(t != -1)) {
+ if (LIKELY(t != -1)) {
return t;
}
@@ -751,7 +751,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
break;
}
- else if (PIL_check_seconds_timer() - t >= ms * 0.001) {
+ if (PIL_check_seconds_timer() - t >= ms * 0.001) {
break;
}
}
diff --git a/source/blender/blenlib/intern/voronoi_2d.c b/source/blender/blenlib/intern/voronoi_2d.c
index bc11a2c7a1c..5b998973a20 100644
--- a/source/blender/blenlib/intern/voronoi_2d.c
+++ b/source/blender/blenlib/intern/voronoi_2d.c
@@ -83,7 +83,9 @@ static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event)
}
/* edge */
-static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2])
+static VoronoiEdge *voronoiEdge_new(const float start[2],
+ const float left[2],
+ const float right[2])
{
VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge");
@@ -118,7 +120,7 @@ static VoronoiParabola *voronoiParabola_new(void)
return parabola;
}
-static VoronoiParabola *voronoiParabola_newSite(float site[2])
+static VoronoiParabola *voronoiParabola_newSite(const float site[2])
{
VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site");
diff --git a/source/blender/blenlib/tests/BLI_array_test.cc b/source/blender/blenlib/tests/BLI_array_test.cc
new file mode 100644
index 00000000000..7348a6f93f3
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_array_test.cc
@@ -0,0 +1,176 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_array.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(array, DefaultConstructor)
+{
+ Array<int> array;
+ EXPECT_EQ(array.size(), 0);
+ EXPECT_TRUE(array.is_empty());
+}
+
+TEST(array, SizeConstructor)
+{
+ Array<int> array(5);
+ EXPECT_EQ(array.size(), 5);
+ EXPECT_FALSE(array.is_empty());
+}
+
+TEST(array, FillConstructor)
+{
+ Array<int> array(5, 8);
+ EXPECT_EQ(array.size(), 5);
+ EXPECT_EQ(array[0], 8);
+ EXPECT_EQ(array[1], 8);
+ EXPECT_EQ(array[2], 8);
+ EXPECT_EQ(array[3], 8);
+ EXPECT_EQ(array[4], 8);
+}
+
+TEST(array, InitializerListConstructor)
+{
+ Array<int> array = {4, 5, 6, 7};
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array[0], 4);
+ EXPECT_EQ(array[1], 5);
+ EXPECT_EQ(array[2], 6);
+ EXPECT_EQ(array[3], 7);
+}
+
+TEST(array, SpanConstructor)
+{
+ int stackarray[4] = {6, 7, 8, 9};
+ Span<int> span(stackarray, ARRAY_SIZE(stackarray));
+ Array<int> array(span);
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(array[0], 6);
+ EXPECT_EQ(array[1], 7);
+ EXPECT_EQ(array[2], 8);
+ EXPECT_EQ(array[3], 9);
+}
+
+TEST(array, CopyConstructor)
+{
+ Array<int> array = {5, 6, 7, 8};
+ Array<int> new_array(array);
+
+ EXPECT_EQ(array.size(), 4);
+ EXPECT_EQ(new_array.size(), 4);
+ EXPECT_NE(array.data(), new_array.data());
+ EXPECT_EQ(new_array[0], 5);
+ EXPECT_EQ(new_array[1], 6);
+ EXPECT_EQ(new_array[2], 7);
+ EXPECT_EQ(new_array[3], 8);
+}
+
+TEST(array, MoveConstructor)
+{
+ Array<int> array = {5, 6, 7, 8};
+ Array<int> new_array(std::move(array));
+
+ EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(new_array.size(), 4);
+ EXPECT_EQ(new_array[0], 5);
+ EXPECT_EQ(new_array[1], 6);
+ EXPECT_EQ(new_array[2], 7);
+ EXPECT_EQ(new_array[3], 8);
+}
+
+TEST(array, CopyAssignment)
+{
+ Array<int> array = {1, 2, 3};
+ Array<int> new_array = {4};
+ EXPECT_EQ(new_array.size(), 1);
+ new_array = array;
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 3);
+ EXPECT_NE(array.data(), new_array.data());
+ EXPECT_EQ(new_array[0], 1);
+ EXPECT_EQ(new_array[1], 2);
+ EXPECT_EQ(new_array[2], 3);
+}
+
+TEST(array, MoveAssignment)
+{
+ Array<int> array = {1, 2, 3};
+ Array<int> new_array = {4};
+ EXPECT_EQ(new_array.size(), 1);
+ new_array = std::move(array);
+ EXPECT_EQ(new_array.size(), 3);
+ EXPECT_EQ(array.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(new_array[0], 1);
+ EXPECT_EQ(new_array[1], 2);
+ EXPECT_EQ(new_array[2], 3);
+}
+
+/**
+ * Tests that the trivially constructible types are not zero-initialized. We do not want that for
+ * performance reasons.
+ */
+TEST(array, TrivialTypeSizeConstructor)
+{
+ Array<char, 1> *array = new Array<char, 1>(1);
+ char *ptr = &(*array)[0];
+ array->~Array();
+
+ const char magic = 42;
+ *ptr = magic;
+ EXPECT_EQ(*ptr, magic);
+
+ new (array) Array<char, 1>(1);
+ EXPECT_EQ((*array)[0], magic);
+ EXPECT_EQ(*ptr, magic);
+ delete array;
+}
+
+struct ConstructibleType {
+ char value;
+
+ ConstructibleType()
+ {
+ value = 42;
+ }
+};
+
+TEST(array, NoInitializationSizeConstructor)
+{
+ using MyArray = Array<ConstructibleType>;
+
+ TypedBuffer<MyArray> buffer;
+ memset((void *)&buffer, 100, sizeof(MyArray));
+
+ /* Doing this to avoid some compiler optimization. */
+ for (int64_t i : IndexRange(sizeof(MyArray))) {
+ EXPECT_EQ(((char *)buffer.ptr())[i], 100);
+ }
+
+ {
+ MyArray &array = *new (buffer) MyArray(1, NoInitialization());
+ EXPECT_EQ(array[0].value, 100);
+ array.clear_without_destruct();
+ array.~Array();
+ }
+ {
+ MyArray &array = *new (buffer) MyArray(1);
+ EXPECT_EQ(array[0].value, 42);
+ array.~Array();
+ }
+}
+
+TEST(array, Fill)
+{
+ Array<int> array(5);
+ array.fill(3);
+ EXPECT_EQ(array.size(), 5u);
+ EXPECT_EQ(array[0], 3);
+ EXPECT_EQ(array[1], 3);
+ EXPECT_EQ(array[2], 3);
+ EXPECT_EQ(array[3], 3);
+ EXPECT_EQ(array[4], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_disjoint_set_test.cc b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc
new file mode 100644
index 00000000000..f30ee610b2a
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_disjoint_set_test.cc
@@ -0,0 +1,36 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_disjoint_set.hh"
+#include "BLI_strict_flags.h"
+
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(disjoint_set, Test)
+{
+ DisjointSet disjoint_set(6);
+ EXPECT_FALSE(disjoint_set.in_same_set(1, 2));
+ EXPECT_FALSE(disjoint_set.in_same_set(5, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(2, 2));
+ EXPECT_EQ(disjoint_set.find_root(3), 3);
+
+ disjoint_set.join(1, 2);
+
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 2));
+ EXPECT_FALSE(disjoint_set.in_same_set(0, 1));
+
+ disjoint_set.join(3, 4);
+
+ EXPECT_FALSE(disjoint_set.in_same_set(2, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(3, 4));
+
+ disjoint_set.join(1, 4);
+
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 4));
+ EXPECT_TRUE(disjoint_set.in_same_set(1, 3));
+ EXPECT_TRUE(disjoint_set.in_same_set(2, 4));
+ EXPECT_FALSE(disjoint_set.in_same_set(0, 4));
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_edgehash_test.cc b/source/blender/blenlib/tests/BLI_edgehash_test.cc
new file mode 100644
index 00000000000..7106033df36
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_edgehash_test.cc
@@ -0,0 +1,408 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+#include <algorithm>
+#include <random>
+#include <vector>
+
+#include "BLI_edgehash.h"
+#include "BLI_utildefines.h"
+
+#define VALUE_1 POINTER_FROM_INT(1)
+#define VALUE_2 POINTER_FROM_INT(2)
+#define VALUE_3 POINTER_FROM_INT(3)
+
+TEST(edgehash, InsertIncreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertNewIncreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertExistingDoesNotIncreaseLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ BLI_edgehash_reinsert(eh, 2, 1, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ReinsertCanChangeValue)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+ BLI_edgehash_reinsert(eh, 2, 1, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+ BLI_edgehash_reinsert(eh, 1, 2, VALUE_3);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_3);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupNonExistingWithDefault)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupExistingWithDefault)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup_default(eh, 1, 2, VALUE_2), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupPExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ void *value = VALUE_1;
+ BLI_edgehash_insert(eh, 1, 2, value);
+ void **value_p = BLI_edgehash_lookup_p(eh, 1, 2);
+ ASSERT_EQ(*value_p, VALUE_1);
+ *value_p = VALUE_2;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupPNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_EQ(BLI_edgehash_lookup_p(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, EnsurePNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ void **value_p;
+ bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p);
+ ASSERT_FALSE(existed);
+ *value_p = VALUE_1;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, EnsurePExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ void **value_p;
+ bool existed = BLI_edgehash_ensure_p(eh, 1, 2, &value_p);
+ ASSERT_TRUE(existed);
+ ASSERT_EQ(*value_p, VALUE_1);
+ *value_p = VALUE_2;
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 1, 2), VALUE_2);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, RemoveExistingDecreasesLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ bool has_been_removed = BLI_edgehash_remove(eh, 1, 2, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+ ASSERT_TRUE(has_been_removed);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, RemoveNonExistingDoesNotDecreaseLength)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ bool has_been_removed = BLI_edgehash_remove(eh, 4, 5, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+ ASSERT_FALSE(has_been_removed);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, PopKeyTwice)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), VALUE_1);
+ ASSERT_EQ(BLI_edgehash_popkey(eh, 1, 2), nullptr);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, LookupInvertedIndices)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_EQ(BLI_edgehash_lookup(eh, 2, 1), VALUE_1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, HasKeyExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ ASSERT_TRUE(BLI_edgehash_haskey(eh, 1, 2));
+ ASSERT_TRUE(BLI_edgehash_haskey(eh, 2, 1));
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, HasKeyNonExisting)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ ASSERT_FALSE(BLI_edgehash_haskey(eh, 1, 2));
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, ClearSetsLengthToZero)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 2, VALUE_2);
+ ASSERT_EQ(BLI_edgehash_len(eh), 2);
+ BLI_edgehash_clear(eh, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, IteratorFindsAllValues)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+
+ EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh);
+ auto a = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+ auto b = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+ auto c = BLI_edgehashIterator_getValue(ehi);
+ BLI_edgehashIterator_step(ehi);
+
+ ASSERT_NE(a, b);
+ ASSERT_NE(b, c);
+ ASSERT_NE(a, c);
+ ASSERT_TRUE(ELEM(a, VALUE_1, VALUE_2, VALUE_3));
+ ASSERT_TRUE(ELEM(b, VALUE_1, VALUE_2, VALUE_3));
+ ASSERT_TRUE(ELEM(c, VALUE_1, VALUE_2, VALUE_3));
+
+ BLI_edgehashIterator_free(ehi);
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, IterateIsDone)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+
+ EdgeHashIterator *ehi = BLI_edgehashIterator_new(eh);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_FALSE(BLI_edgehashIterator_isDone(ehi));
+ BLI_edgehashIterator_step(ehi);
+ ASSERT_TRUE(BLI_edgehashIterator_isDone(ehi));
+
+ BLI_edgehashIterator_free(ehi);
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgehash, DoubleRemove)
+{
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ BLI_edgehash_insert(eh, 1, 2, VALUE_1);
+ BLI_edgehash_insert(eh, 1, 3, VALUE_2);
+ BLI_edgehash_insert(eh, 1, 4, VALUE_3);
+ ASSERT_EQ(BLI_edgehash_len(eh), 3);
+
+ BLI_edgehash_remove(eh, 1, 2, nullptr);
+ BLI_edgehash_remove(eh, 1, 3, nullptr);
+ ASSERT_EQ(BLI_edgehash_len(eh), 1);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+struct Edge {
+ uint v1, v2;
+};
+
+TEST(edgehash, StressTest)
+{
+ std::srand(0);
+ int amount = 10000;
+
+ std::vector<Edge> edges;
+ for (int i = 0; i < amount; i++) {
+ edges.push_back({(uint)i, amount + (uint)std::rand() % 12345});
+ }
+
+ EdgeHash *eh = BLI_edgehash_new(__func__);
+
+ /* first insert all the edges */
+ for (int i = 0; i < edges.size(); i++) {
+ BLI_edgehash_insert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i));
+ }
+
+ std::vector<Edge> shuffled = edges;
+ std::shuffle(shuffled.begin(), shuffled.end(), std::default_random_engine());
+
+ /* then remove half of them */
+ int remove_until = shuffled.size() / 2;
+ for (int i = 0; i < remove_until; i++) {
+ BLI_edgehash_remove(eh, shuffled[i].v2, shuffled[i].v1, nullptr);
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), edges.size() - remove_until);
+
+ /* check if the right ones have been removed */
+ for (int i = 0; i < shuffled.size(); i++) {
+ bool haskey = BLI_edgehash_haskey(eh, shuffled[i].v1, shuffled[i].v2);
+ if (i < remove_until) {
+ ASSERT_FALSE(haskey);
+ }
+ else {
+ ASSERT_TRUE(haskey);
+ }
+ }
+
+ /* reinsert all edges */
+ for (int i = 0; i < edges.size(); i++) {
+ BLI_edgehash_reinsert(eh, edges[i].v1, edges[i].v2, POINTER_FROM_INT(i));
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), edges.size());
+
+ /* pop all edges */
+ for (int i = 0; i < edges.size(); i++) {
+ int value = POINTER_AS_INT(BLI_edgehash_popkey(eh, edges[i].v1, edges[i].v2));
+ ASSERT_EQ(i, value);
+ }
+
+ ASSERT_EQ(BLI_edgehash_len(eh), 0);
+
+ BLI_edgehash_free(eh, nullptr);
+}
+
+TEST(edgeset, AddNonExistingIncreasesLength)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_EQ(BLI_edgeset_len(es), 0);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 1, 3);
+ ASSERT_EQ(BLI_edgeset_len(es), 2);
+ BLI_edgeset_add(es, 1, 4);
+ ASSERT_EQ(BLI_edgeset_len(es), 3);
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, AddExistingDoesNotIncreaseLength)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_EQ(BLI_edgeset_len(es), 0);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 2, 1);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+ BLI_edgeset_add(es, 1, 2);
+ ASSERT_EQ(BLI_edgeset_len(es), 1);
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, HasKeyNonExisting)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ ASSERT_FALSE(BLI_edgeset_haskey(es, 1, 2));
+
+ BLI_edgeset_free(es);
+}
+
+TEST(edgeset, HasKeyExisting)
+{
+ EdgeSet *es = BLI_edgeset_new(__func__);
+
+ BLI_edgeset_insert(es, 1, 2);
+ ASSERT_TRUE(BLI_edgeset_haskey(es, 1, 2));
+
+ BLI_edgeset_free(es);
+}
diff --git a/source/blender/blenlib/tests/BLI_index_mask_test.cc b/source/blender/blenlib/tests/BLI_index_mask_test.cc
new file mode 100644
index 00000000000..4d6060e51c9
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_index_mask_test.cc
@@ -0,0 +1,43 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_index_mask.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(index_mask, DefaultConstructor)
+{
+ IndexMask mask;
+ EXPECT_EQ(mask.min_array_size(), 0);
+ EXPECT_EQ(mask.size(), 0);
+}
+
+TEST(index_mask, ArrayConstructor)
+{
+ [](IndexMask mask) {
+ EXPECT_EQ(mask.size(), 4);
+ EXPECT_EQ(mask.min_array_size(), 8);
+ EXPECT_FALSE(mask.is_range());
+ EXPECT_EQ(mask[0], 3);
+ EXPECT_EQ(mask[1], 5);
+ EXPECT_EQ(mask[2], 6);
+ EXPECT_EQ(mask[3], 7);
+ }({3, 5, 6, 7});
+}
+
+TEST(index_mask, RangeConstructor)
+{
+ IndexMask mask = IndexRange(3, 5);
+ EXPECT_EQ(mask.size(), 5);
+ EXPECT_EQ(mask.min_array_size(), 8);
+ EXPECT_EQ(mask.last(), 7);
+ EXPECT_TRUE(mask.is_range());
+ EXPECT_EQ(mask.as_range().first(), 3);
+ EXPECT_EQ(mask.as_range().last(), 7);
+ Span<int64_t> indices = mask.indices();
+ EXPECT_EQ(indices[0], 3);
+ EXPECT_EQ(indices[1], 4);
+ EXPECT_EQ(indices[2], 5);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_index_range_test.cc b/source/blender/blenlib/tests/BLI_index_range_test.cc
new file mode 100644
index 00000000000..d472ded0f18
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_index_range_test.cc
@@ -0,0 +1,143 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_index_range.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(index_range, DefaultConstructor)
+{
+ IndexRange range;
+ EXPECT_EQ(range.size(), 0);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+ EXPECT_EQ(vector.size(), 0);
+}
+
+TEST(index_range, SingleElementRange)
+{
+ IndexRange range(4, 1);
+ EXPECT_EQ(range.size(), 1);
+ EXPECT_EQ(*range.begin(), 4);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+
+ EXPECT_EQ(vector.size(), 1);
+ EXPECT_EQ(vector[0], 4);
+}
+
+TEST(index_range, MultipleElementRange)
+{
+ IndexRange range(6, 4);
+ EXPECT_EQ(range.size(), 4);
+
+ Vector<int64_t> vector;
+ for (int64_t value : range) {
+ vector.append(value);
+ }
+
+ EXPECT_EQ(vector.size(), 4);
+ for (int i = 0; i < 4; i++) {
+ EXPECT_EQ(vector[i], i + 6);
+ }
+}
+
+TEST(index_range, SubscriptOperator)
+{
+ IndexRange range(5, 5);
+ EXPECT_EQ(range[0], 5);
+ EXPECT_EQ(range[1], 6);
+ EXPECT_EQ(range[2], 7);
+}
+
+TEST(index_range, Before)
+{
+ IndexRange range = IndexRange(5, 5).before(3);
+ EXPECT_EQ(range[0], 2);
+ EXPECT_EQ(range[1], 3);
+ EXPECT_EQ(range[2], 4);
+ EXPECT_EQ(range.size(), 3);
+}
+
+TEST(index_range, After)
+{
+ IndexRange range = IndexRange(5, 5).after(4);
+ EXPECT_EQ(range[0], 10);
+ EXPECT_EQ(range[1], 11);
+ EXPECT_EQ(range[2], 12);
+ EXPECT_EQ(range[3], 13);
+ EXPECT_EQ(range.size(), 4);
+}
+
+TEST(index_range, Contains)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_TRUE(range.contains(5));
+ EXPECT_TRUE(range.contains(6));
+ EXPECT_TRUE(range.contains(7));
+ EXPECT_FALSE(range.contains(4));
+ EXPECT_FALSE(range.contains(8));
+}
+
+TEST(index_range, First)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.first(), 5);
+}
+
+TEST(index_range, Last)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.last(), 7);
+}
+
+TEST(index_range, OneAfterEnd)
+{
+ IndexRange range = IndexRange(5, 3);
+ EXPECT_EQ(range.one_after_last(), 8);
+}
+
+TEST(index_range, Start)
+{
+ IndexRange range = IndexRange(6, 2);
+ EXPECT_EQ(range.start(), 6);
+}
+
+TEST(index_range, Slice)
+{
+ IndexRange range = IndexRange(5, 15);
+ IndexRange slice = range.slice(2, 6);
+ EXPECT_EQ(slice.size(), 6);
+ EXPECT_EQ(slice.first(), 7);
+ EXPECT_EQ(slice.last(), 12);
+}
+
+TEST(index_range, SliceRange)
+{
+ IndexRange range = IndexRange(5, 15);
+ IndexRange slice = range.slice(IndexRange(3, 5));
+ EXPECT_EQ(slice.size(), 5);
+ EXPECT_EQ(slice.first(), 8);
+ EXPECT_EQ(slice.last(), 12);
+}
+
+TEST(index_range, AsSpan)
+{
+ IndexRange range = IndexRange(4, 6);
+ Span<int64_t> span = range.as_span();
+ EXPECT_EQ(span.size(), 6);
+ EXPECT_EQ(span[0], 4);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(span[3], 7);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
new file mode 100644
index 00000000000..44b70d1f55d
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc
@@ -0,0 +1,118 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_linear_allocator.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+static bool is_aligned(void *ptr, uint alignment)
+{
+ BLI_assert(is_power_of_2_i((int)alignment));
+ return (POINTER_AS_UINT(ptr) & (alignment - 1)) == 0;
+}
+
+TEST(linear_allocator, AllocationAlignment)
+{
+ LinearAllocator<> allocator;
+
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 16), 16));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 4), 4));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 64), 64));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 8), 8));
+ EXPECT_TRUE(is_aligned(allocator.allocate(10, 128), 128));
+}
+
+TEST(linear_allocator, PackedAllocation)
+{
+ LinearAllocator<> allocator;
+ blender::AlignedBuffer<256, 32> buffer;
+ allocator.provide_buffer(buffer);
+
+ uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /* 0 - 10 */
+ uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */
+ uintptr_t ptr3 = (uintptr_t)allocator.allocate(8, 32); /* 32 - 40 */
+ uintptr_t ptr4 = (uintptr_t)allocator.allocate(16, 8); /* 40 - 56 */
+ uintptr_t ptr5 = (uintptr_t)allocator.allocate(1, 8); /* 56 - 57 */
+ uintptr_t ptr6 = (uintptr_t)allocator.allocate(1, 4); /* 60 - 61 */
+ uintptr_t ptr7 = (uintptr_t)allocator.allocate(1, 1); /* 61 - 62 */
+
+ EXPECT_EQ(ptr2 - ptr1, 12); /* 12 - 0 = 12 */
+ EXPECT_EQ(ptr3 - ptr2, 20); /* 32 - 12 = 20 */
+ EXPECT_EQ(ptr4 - ptr3, 8); /* 40 - 32 = 8 */
+ EXPECT_EQ(ptr5 - ptr4, 16); /* 56 - 40 = 16 */
+ EXPECT_EQ(ptr6 - ptr5, 4); /* 60 - 56 = 4 */
+ EXPECT_EQ(ptr7 - ptr6, 1); /* 61 - 60 = 1 */
+}
+
+TEST(linear_allocator, CopyString)
+{
+ LinearAllocator<> allocator;
+ blender::AlignedBuffer<256, 1> buffer;
+ allocator.provide_buffer(buffer);
+
+ StringRefNull ref1 = allocator.copy_string("Hello");
+ StringRefNull ref2 = allocator.copy_string("World");
+
+ EXPECT_EQ(ref1, "Hello");
+ EXPECT_EQ(ref2, "World");
+ EXPECT_EQ(ref2.data() - ref1.data(), 6);
+}
+
+TEST(linear_allocator, AllocateArray)
+{
+ LinearAllocator<> allocator;
+
+ MutableSpan<int> span = allocator.allocate_array<int>(5);
+ EXPECT_EQ(span.size(), 5);
+}
+
+TEST(linear_allocator, Construct)
+{
+ LinearAllocator<> allocator;
+
+ std::array<int, 5> values = {1, 2, 3, 4, 5};
+ Vector<int> *vector = allocator.construct<Vector<int>>(values);
+ EXPECT_EQ(vector->size(), 5);
+ EXPECT_EQ((*vector)[3], 4);
+ vector->~Vector();
+}
+
+TEST(linear_allocator, ConstructElementsAndPointerArray)
+{
+ LinearAllocator<> allocator;
+
+ std::array<int, 7> values = {1, 2, 3, 4, 5, 6, 7};
+ Span<Vector<int> *> vectors = allocator.construct_elements_and_pointer_array<Vector<int>>(
+ 5, values);
+
+ EXPECT_EQ(vectors.size(), 5);
+ EXPECT_EQ(vectors[3]->size(), 7);
+ EXPECT_EQ((*vectors[2])[5], 6);
+
+ for (Vector<int> *vector : vectors) {
+ vector->~Vector();
+ }
+}
+
+TEST(linear_allocator, ConstructArrayCopy)
+{
+ LinearAllocator<> allocator;
+
+ Vector<int> values = {1, 2, 3};
+ MutableSpan<int> span1 = allocator.construct_array_copy(values.as_span());
+ MutableSpan<int> span2 = allocator.construct_array_copy(values.as_span());
+ EXPECT_NE(span1.data(), span2.data());
+ EXPECT_EQ(span1.size(), 3);
+ EXPECT_EQ(span2.size(), 3);
+ EXPECT_EQ(span1[1], 2);
+ EXPECT_EQ(span2[2], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc
new file mode 100644
index 00000000000..fe7b0f01279
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_map_test.cc
@@ -0,0 +1,590 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_map.hh"
+#include "BLI_rand.h"
+#include "BLI_set.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_timeit.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(map, DefaultConstructor)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_TRUE(map.is_empty());
+}
+
+TEST(map, AddIncreasesSize)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_TRUE(map.is_empty());
+ map.add(2, 5.0f);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_FALSE(map.is_empty());
+ map.add(6, 2.0f);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_FALSE(map.is_empty());
+}
+
+TEST(map, Contains)
+{
+ Map<int, float> map;
+ EXPECT_FALSE(map.contains(4));
+ map.add(5, 6.0f);
+ EXPECT_FALSE(map.contains(4));
+ map.add(4, 2.0f);
+ EXPECT_TRUE(map.contains(4));
+}
+
+TEST(map, LookupExisting)
+{
+ Map<int, float> map;
+ map.add(2, 6.0f);
+ map.add(4, 1.0f);
+ EXPECT_EQ(map.lookup(2), 6.0f);
+ EXPECT_EQ(map.lookup(4), 1.0f);
+}
+
+TEST(map, LookupNotExisting)
+{
+ Map<int, float> map;
+ map.add(2, 4.0f);
+ map.add(1, 1.0f);
+ EXPECT_EQ(map.lookup_ptr(0), nullptr);
+ EXPECT_EQ(map.lookup_ptr(5), nullptr);
+}
+
+TEST(map, AddMany)
+{
+ Map<int, int> map;
+ for (int i = 0; i < 100; i++) {
+ map.add(i * 30, i);
+ map.add(i * 31, i);
+ }
+}
+
+TEST(map, PopItem)
+{
+ Map<int, float> map;
+ map.add(2, 3.0f);
+ map.add(1, 9.0f);
+ EXPECT_TRUE(map.contains(2));
+ EXPECT_TRUE(map.contains(1));
+
+ EXPECT_EQ(map.pop(1), 9.0f);
+ EXPECT_TRUE(map.contains(2));
+ EXPECT_FALSE(map.contains(1));
+
+ EXPECT_EQ(map.pop(2), 3.0f);
+ EXPECT_FALSE(map.contains(2));
+ EXPECT_FALSE(map.contains(1));
+}
+
+TEST(map, PopTry)
+{
+ Map<int, int> map;
+ map.add(1, 5);
+ map.add(2, 7);
+ EXPECT_EQ(map.size(), 2);
+ std::optional<int> value = map.pop_try(4);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_FALSE(value.has_value());
+ value = map.pop_try(2);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_TRUE(value.has_value());
+ EXPECT_EQ(*value, 7);
+ EXPECT_EQ(*map.pop_try(1), 5);
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PopDefault)
+{
+ Map<int, int> map;
+ map.add(1, 4);
+ map.add(2, 7);
+ map.add(3, 8);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.pop_default(4, 10), 10);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_EQ(map.pop_default(1, 10), 4);
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_EQ(map.pop_default(2, 20), 7);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.pop_default(2, 20), 20);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_EQ(map.pop_default(3, 0), 8);
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PopItemMany)
+{
+ Map<int, int> map;
+ for (int i = 0; i < 100; i++) {
+ map.add_new(i, i);
+ }
+ for (int i = 25; i < 80; i++) {
+ EXPECT_EQ(map.pop(i), i);
+ }
+ for (int i = 0; i < 100; i++) {
+ EXPECT_EQ(map.contains(i), i < 25 || i >= 80);
+ }
+}
+
+TEST(map, ValueIterator)
+{
+ Map<int, float> map;
+ map.add(3, 5.0f);
+ map.add(1, 2.0f);
+ map.add(7, -2.0f);
+
+ blender::Set<float> values;
+
+ int iterations = 0;
+ for (float value : map.values()) {
+ values.add(value);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(values.contains(5.0f));
+ EXPECT_TRUE(values.contains(-2.0f));
+ EXPECT_TRUE(values.contains(2.0f));
+}
+
+TEST(map, KeyIterator)
+{
+ Map<int, float> map;
+ map.add(6, 3.0f);
+ map.add(2, 4.0f);
+ map.add(1, 3.0f);
+
+ blender::Set<int> keys;
+
+ int iterations = 0;
+ for (int key : map.keys()) {
+ keys.add(key);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(keys.contains(1));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(keys.contains(6));
+}
+
+TEST(map, ItemIterator)
+{
+ Map<int, float> map;
+ map.add(5, 3.0f);
+ map.add(2, 9.0f);
+ map.add(1, 0.0f);
+
+ blender::Set<int> keys;
+ blender::Set<float> values;
+
+ int iterations = 0;
+ const Map<int, float> &const_map = map;
+ for (auto item : const_map.items()) {
+ keys.add(item.key);
+ values.add(item.value);
+ iterations++;
+ }
+
+ EXPECT_EQ(iterations, 3);
+ EXPECT_TRUE(keys.contains(5));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(keys.contains(1));
+ EXPECT_TRUE(values.contains(3.0f));
+ EXPECT_TRUE(values.contains(9.0f));
+ EXPECT_TRUE(values.contains(0.0f));
+}
+
+TEST(map, MutableValueIterator)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ for (int &value : map.values()) {
+ value += 10;
+ }
+
+ EXPECT_EQ(map.lookup(3), 16);
+ EXPECT_EQ(map.lookup(2), 11);
+}
+
+TEST(map, MutableItemIterator)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ for (auto item : map.items()) {
+ item.value += item.key;
+ }
+
+ EXPECT_EQ(map.lookup(3), 9.0f);
+ EXPECT_EQ(map.lookup(2), 3.0f);
+}
+
+TEST(map, MutableItemToItemConversion)
+{
+ Map<int, int> map;
+ map.add(3, 6);
+ map.add(2, 1);
+
+ Vector<int> keys, values;
+ for (Map<int, int>::Item item : map.items()) {
+ keys.append(item.key);
+ values.append(item.value);
+ }
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
+ EXPECT_TRUE(keys.contains(3));
+ EXPECT_TRUE(keys.contains(2));
+ EXPECT_TRUE(values.contains(6));
+ EXPECT_TRUE(values.contains(1));
+}
+
+static float return_42()
+{
+ return 42.0f;
+}
+
+TEST(map, LookupOrAddCB_SeparateFunction)
+{
+ Map<int, float> map;
+ EXPECT_EQ(map.lookup_or_add_cb(0, return_42), 42.0f);
+ EXPECT_EQ(map.lookup(0), 42);
+
+ map.keys();
+}
+
+TEST(map, LookupOrAddCB_Lambdas)
+{
+ Map<int, float> map;
+ auto lambda1 = []() { return 11.0f; };
+ EXPECT_EQ(map.lookup_or_add_cb(0, lambda1), 11.0f);
+ auto lambda2 = []() { return 20.0f; };
+ EXPECT_EQ(map.lookup_or_add_cb(1, lambda2), 20.0f);
+
+ EXPECT_EQ(map.lookup_or_add_cb(0, lambda2), 11.0f);
+ EXPECT_EQ(map.lookup_or_add_cb(1, lambda1), 20.0f);
+}
+
+TEST(map, AddOrModify)
+{
+ Map<int, float> map;
+ auto create_func = [](float *value) {
+ *value = 10.0f;
+ return true;
+ };
+ auto modify_func = [](float *value) {
+ *value += 5;
+ return false;
+ };
+ EXPECT_TRUE(map.add_or_modify(1, create_func, modify_func));
+ EXPECT_EQ(map.lookup(1), 10.0f);
+ EXPECT_FALSE(map.add_or_modify(1, create_func, modify_func));
+ EXPECT_EQ(map.lookup(1), 15.0f);
+}
+
+TEST(map, AddOverwrite)
+{
+ Map<int, float> map;
+ EXPECT_FALSE(map.contains(3));
+ EXPECT_TRUE(map.add_overwrite(3, 6.0f));
+ EXPECT_EQ(map.lookup(3), 6.0f);
+ EXPECT_FALSE(map.add_overwrite(3, 7.0f));
+ EXPECT_EQ(map.lookup(3), 7.0f);
+ EXPECT_FALSE(map.add(3, 8.0f));
+ EXPECT_EQ(map.lookup(3), 7.0f);
+}
+
+TEST(map, LookupOrAddDefault)
+{
+ Map<int, float> map;
+ map.lookup_or_add_default(3) = 6;
+ EXPECT_EQ(map.lookup(3), 6);
+ map.lookup_or_add_default(5) = 2;
+ EXPECT_EQ(map.lookup(5), 2);
+ map.lookup_or_add_default(3) += 4;
+ EXPECT_EQ(map.lookup(3), 10);
+}
+
+TEST(map, LookupOrAdd)
+{
+ Map<int, int> map;
+ EXPECT_EQ(map.lookup_or_add(6, 4), 4);
+ EXPECT_EQ(map.lookup_or_add(6, 5), 4);
+ map.lookup_or_add(6, 4) += 10;
+ EXPECT_EQ(map.lookup(6), 14);
+}
+
+TEST(map, MoveConstructorSmall)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2(std::move(map1));
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, MoveConstructorLarge)
+{
+ Map<int, int> map1;
+ for (int i = 0; i < 100; i++) {
+ map1.add_new(i, i);
+ }
+ Map<int, int> map2(std::move(map1));
+ EXPECT_EQ(map2.size(), 100);
+ EXPECT_EQ(map2.lookup(1), 1);
+ EXPECT_EQ(map2.lookup(4), 4);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, MoveAssignment)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2;
+ map2 = std::move(map1);
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(map1.lookup_ptr(4), nullptr);
+}
+
+TEST(map, CopyAssignment)
+{
+ Map<int, float> map1;
+ map1.add(1, 2.0f);
+ map1.add(4, 1.0f);
+ Map<int, float> map2;
+ map2 = map1;
+ EXPECT_EQ(map2.size(), 2);
+ EXPECT_EQ(map2.lookup(1), 2.0f);
+ EXPECT_EQ(map2.lookup(4), 1.0f);
+ EXPECT_EQ(map1.size(), 2);
+ EXPECT_EQ(*map1.lookup_ptr(4), 1.0f);
+}
+
+TEST(map, Clear)
+{
+ Map<int, float> map;
+ map.add(1, 1.0f);
+ map.add(2, 5.0f);
+
+ EXPECT_EQ(map.size(), 2);
+ EXPECT_TRUE(map.contains(1));
+ EXPECT_TRUE(map.contains(2));
+
+ map.clear();
+
+ EXPECT_EQ(map.size(), 0);
+ EXPECT_FALSE(map.contains(1));
+ EXPECT_FALSE(map.contains(2));
+}
+
+TEST(map, UniquePtrValue)
+{
+ auto value1 = std::unique_ptr<int>(new int());
+ auto value2 = std::unique_ptr<int>(new int());
+ auto value3 = std::unique_ptr<int>(new int());
+
+ int *value1_ptr = value1.get();
+
+ Map<int, std::unique_ptr<int>> map;
+ map.add_new(1, std::move(value1));
+ map.add(2, std::move(value2));
+ map.add_overwrite(3, std::move(value3));
+ map.lookup_or_add_cb(4, []() { return std::unique_ptr<int>(new int()); });
+ map.add_new(5, std::unique_ptr<int>(new int()));
+ map.add(6, std::unique_ptr<int>(new int()));
+ map.add_overwrite(7, std::unique_ptr<int>(new int()));
+ map.lookup_or_add(8, std::unique_ptr<int>(new int()));
+ map.pop_default(9, std::unique_ptr<int>(new int()));
+
+ EXPECT_EQ(map.lookup(1).get(), value1_ptr);
+ EXPECT_EQ(map.lookup_ptr(100), nullptr);
+}
+
+TEST(map, Remove)
+{
+ Map<int, int> map;
+ map.add(2, 4);
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_FALSE(map.remove(3));
+ EXPECT_EQ(map.size(), 1);
+ EXPECT_TRUE(map.remove(2));
+ EXPECT_EQ(map.size(), 0);
+}
+
+TEST(map, PointerKeys)
+{
+ char a, b, c, d;
+
+ Map<char *, int> map;
+ EXPECT_TRUE(map.add(&a, 5));
+ EXPECT_FALSE(map.add(&a, 4));
+ map.add_new(&b, 1);
+ map.add_new(&c, 1);
+ EXPECT_EQ(map.size(), 3);
+ EXPECT_TRUE(map.remove(&b));
+ EXPECT_TRUE(map.add(&b, 8));
+ EXPECT_FALSE(map.remove(&d));
+ EXPECT_TRUE(map.remove(&a));
+ EXPECT_TRUE(map.remove(&b));
+ EXPECT_TRUE(map.remove(&c));
+ EXPECT_TRUE(map.is_empty());
+}
+
+TEST(map, ConstKeysAndValues)
+{
+ Map<const std::string, const std::string> map;
+ map.reserve(10);
+ map.add("45", "643");
+ EXPECT_TRUE(map.contains("45"));
+ EXPECT_FALSE(map.contains("54"));
+}
+
+TEST(map, ForeachItem)
+{
+ Map<int, int> map;
+ map.add(3, 4);
+ map.add(1, 8);
+
+ Vector<int> keys;
+ Vector<int> values;
+ map.foreach_item([&](int key, int value) {
+ keys.append(key);
+ values.append(value);
+ });
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_EQ(values.size(), 2);
+ EXPECT_EQ(keys.first_index_of(3), values.first_index_of(4));
+ EXPECT_EQ(keys.first_index_of(1), values.first_index_of(8));
+}
+
+/**
+ * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
+ */
+#if 0
+template<typename MapT>
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
+{
+ RNG *rng = BLI_rng_new(0);
+ Vector<int> values;
+ for (int i = 0; i < amount; i++) {
+ values.append(BLI_rng_get_int(rng) * factor);
+ }
+ BLI_rng_free(rng);
+
+ MapT map;
+ {
+ SCOPED_TIMER(name + " Add");
+ for (int value : values) {
+ map.add(value, value);
+ }
+ }
+ int count = 0;
+ {
+ SCOPED_TIMER(name + " Contains");
+ for (int value : values) {
+ count += map.contains(value);
+ }
+ }
+ {
+ SCOPED_TIMER(name + " Remove");
+ for (int value : values) {
+ count += map.remove(value);
+ }
+ }
+
+ /* Print the value for simple error checking and to avoid some compiler optimizations. */
+ std::cout << "Count: " << count << "\n";
+}
+
+TEST(map, Benchmark)
+{
+ for (int i = 0; i < 3; i++) {
+ benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, 1);
+ benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>("std::unordered_map", 1000000, 1);
+ }
+ std::cout << "\n";
+ for (int i = 0; i < 3; i++) {
+ uint32_t factor = (3 << 10);
+ benchmark_random_ints<blender::Map<int, int>>("blender::Map ", 1000000, factor);
+ benchmark_random_ints<blender::StdUnorderedMapWrapper<int, int>>(
+ "std::unordered_map", 1000000, factor);
+ }
+}
+
+/**
+ * Timer 'blender::Map Add' took 61.7616 ms
+ * Timer 'blender::Map Contains' took 18.4989 ms
+ * Timer 'blender::Map Remove' took 20.5864 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 188.674 ms
+ * Timer 'std::unordered_map Contains' took 44.3741 ms
+ * Timer 'std::unordered_map Remove' took 169.52 ms
+ * Count: 1999755
+ * Timer 'blender::Map Add' took 37.9196 ms
+ * Timer 'blender::Map Contains' took 16.7361 ms
+ * Timer 'blender::Map Remove' took 20.9568 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 166.09 ms
+ * Timer 'std::unordered_map Contains' took 40.6133 ms
+ * Timer 'std::unordered_map Remove' took 142.85 ms
+ * Count: 1999755
+ * Timer 'blender::Map Add' took 37.3053 ms
+ * Timer 'blender::Map Contains' took 16.6731 ms
+ * Timer 'blender::Map Remove' took 18.8304 ms
+ * Count: 1999755
+ * Timer 'std::unordered_map Add' took 170.964 ms
+ * Timer 'std::unordered_map Contains' took 38.1824 ms
+ * Timer 'std::unordered_map Remove' took 140.263 ms
+ * Count: 1999755
+ *
+ * Timer 'blender::Map Add' took 50.1131 ms
+ * Timer 'blender::Map Contains' took 25.0491 ms
+ * Timer 'blender::Map Remove' took 32.4225 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 150.129 ms
+ * Timer 'std::unordered_map Contains' took 34.6999 ms
+ * Timer 'std::unordered_map Remove' took 120.907 ms
+ * Count: 1889920
+ * Timer 'blender::Map Add' took 50.4438 ms
+ * Timer 'blender::Map Contains' took 25.2677 ms
+ * Timer 'blender::Map Remove' took 32.3047 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 144.015 ms
+ * Timer 'std::unordered_map Contains' took 36.3387 ms
+ * Timer 'std::unordered_map Remove' took 119.109 ms
+ * Count: 1889920
+ * Timer 'blender::Map Add' took 48.6995 ms
+ * Timer 'blender::Map Contains' took 25.1846 ms
+ * Timer 'blender::Map Remove' took 33.0283 ms
+ * Count: 1889920
+ * Timer 'std::unordered_map Add' took 143.494 ms
+ * Timer 'std::unordered_map Contains' took 34.8905 ms
+ * Timer 'std::unordered_map Remove' took 122.739 ms
+ * Count: 1889920
+ */
+
+#endif /* Benchmark */
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_math_base_safe_test.cc b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc
new file mode 100644
index 00000000000..2e3e083cf92
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_math_base_safe_test.cc
@@ -0,0 +1,37 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "BLI_math_base_safe.h"
+
+TEST(math_base, SafePowf)
+{
+ EXPECT_FLOAT_EQ(safe_powf(4.0f, 3.0f), 64.0f);
+ EXPECT_FLOAT_EQ(safe_powf(3.2f, 5.6f), 674.2793796f);
+ EXPECT_FLOAT_EQ(safe_powf(4.0f, -2.0f), 0.0625f);
+ EXPECT_FLOAT_EQ(safe_powf(6.0f, -3.2f), 0.003235311f);
+ EXPECT_FLOAT_EQ(safe_powf(-4.0f, 6), 4096.0f);
+ EXPECT_FLOAT_EQ(safe_powf(-3.0f, 5.5), 0.0f);
+ EXPECT_FLOAT_EQ(safe_powf(-2.5f, -4.0f), 0.0256f);
+ EXPECT_FLOAT_EQ(safe_powf(-3.7f, -4.5f), 0.0f);
+}
+
+TEST(math_base, SafeModf)
+{
+ EXPECT_FLOAT_EQ(safe_modf(3.4, 2.2f), 1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(3.4, -2.2f), 1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(-3.4, -2.2f), -1.2f);
+ EXPECT_FLOAT_EQ(safe_modf(-3.4, 0.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_modf(0.0f, 3.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_modf(55.0f, 10.0f), 5.0f);
+}
+
+TEST(math_base, SafeLogf)
+{
+ EXPECT_FLOAT_EQ(safe_logf(3.3f, 2.5f), 1.302995247f);
+ EXPECT_FLOAT_EQ(safe_logf(0.0f, 3.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(3.0f, 0.0f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(-2.0f, 4.3f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(2.0f, -4.3f), 0.0f);
+ EXPECT_FLOAT_EQ(safe_logf(-2.0f, -4.3f), 0.0f);
+}
diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
new file mode 100644
index 00000000000..f3cb02b63d7
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc
@@ -0,0 +1,159 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_float3.hh"
+#include "BLI_memory_utils.hh"
+#include "BLI_strict_flags.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+struct MyValue {
+ static inline int alive = 0;
+
+ MyValue()
+ {
+ if (alive == 15) {
+ throw std::exception();
+ }
+
+ alive++;
+ }
+
+ MyValue(const MyValue &UNUSED(other))
+ {
+ if (alive == 15) {
+ throw std::exception();
+ }
+
+ alive++;
+ }
+
+ ~MyValue()
+ {
+ alive--;
+ }
+};
+
+TEST(memory_utils, DefaultConstructN_ActuallyCallsConstructor)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, DefaultConstructN_StrongExceptionSafety)
+{
+ constexpr int amount = 20;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ EXPECT_THROW(default_construct_n(buffer.ptr(), amount), std::exception);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedCopyN_ActuallyCopies)
+{
+ constexpr int amount = 5;
+ TypedBuffer<MyValue, amount> buffer1;
+ TypedBuffer<MyValue, amount> buffer2;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr());
+ EXPECT_EQ(MyValue::alive, 2 * amount);
+ destruct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer2.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedCopyN_StrongExceptionSafety)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer1;
+ TypedBuffer<MyValue, amount> buffer2;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ default_construct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, amount);
+ EXPECT_THROW(uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr()), std::exception);
+ EXPECT_EQ(MyValue::alive, amount);
+ destruct_n(buffer1.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedFillN_ActuallyCopies)
+{
+ constexpr int amount = 10;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ {
+ MyValue value;
+ EXPECT_EQ(MyValue::alive, 1);
+ uninitialized_fill_n(buffer.ptr(), amount, value);
+ EXPECT_EQ(MyValue::alive, 1 + amount);
+ destruct_n(buffer.ptr(), amount);
+ EXPECT_EQ(MyValue::alive, 1);
+ }
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+TEST(memory_utils, UninitializedFillN_StrongExceptionSafety)
+{
+ constexpr int amount = 20;
+ TypedBuffer<MyValue, amount> buffer;
+
+ EXPECT_EQ(MyValue::alive, 0);
+ {
+ MyValue value;
+ EXPECT_EQ(MyValue::alive, 1);
+ EXPECT_THROW(uninitialized_fill_n(buffer.ptr(), amount, value), std::exception);
+ EXPECT_EQ(MyValue::alive, 1);
+ }
+ EXPECT_EQ(MyValue::alive, 0);
+}
+
+class TestBaseClass {
+ virtual void mymethod(){};
+};
+
+class TestChildClass : public TestBaseClass {
+ void mymethod() override
+ {
+ }
+};
+
+static_assert(is_convertible_pointer_v<int *, int *>);
+static_assert(is_convertible_pointer_v<int *, const int *>);
+static_assert(is_convertible_pointer_v<int *, int *const>);
+static_assert(is_convertible_pointer_v<int *, const int *const>);
+static_assert(!is_convertible_pointer_v<const int *, int *>);
+static_assert(!is_convertible_pointer_v<int, int *>);
+static_assert(!is_convertible_pointer_v<int *, int>);
+static_assert(is_convertible_pointer_v<TestBaseClass *, const TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<const TestBaseClass *, TestBaseClass *>);
+static_assert(is_convertible_pointer_v<TestChildClass *, TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<TestBaseClass *, TestChildClass *>);
+static_assert(is_convertible_pointer_v<const TestChildClass *, const TestBaseClass *>);
+static_assert(!is_convertible_pointer_v<TestBaseClass, const TestChildClass *>);
+static_assert(!is_convertible_pointer_v<float3, float *>);
+static_assert(!is_convertible_pointer_v<float *, float3>);
+static_assert(!is_convertible_pointer_v<int **, int *>);
+static_assert(!is_convertible_pointer_v<int *, int **>);
+static_assert(is_convertible_pointer_v<int **, int **>);
+static_assert(is_convertible_pointer_v<const int **, const int **>);
+static_assert(!is_convertible_pointer_v<const int **, int **>);
+static_assert(!is_convertible_pointer_v<int *const *, int **>);
+static_assert(!is_convertible_pointer_v<int *const *const, int **>);
+static_assert(is_convertible_pointer_v<int **, int **const>);
+static_assert(is_convertible_pointer_v<int **, int *const *>);
+static_assert(is_convertible_pointer_v<int **, int const *const *>);
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_multi_value_map_test.cc b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc
new file mode 100644
index 00000000000..7501fbe0d87
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_multi_value_map_test.cc
@@ -0,0 +1,109 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_multi_value_map.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(multi_value_map, LookupNotExistant)
+{
+ MultiValueMap<int, int> map;
+ EXPECT_EQ(map.lookup(5).size(), 0);
+ map.add(2, 5);
+ EXPECT_EQ(map.lookup(5).size(), 0);
+}
+
+TEST(multi_value_map, LookupExistant)
+{
+ MultiValueMap<int, int> map;
+ map.add(2, 4);
+ map.add(2, 5);
+ map.add(3, 6);
+
+ EXPECT_EQ(map.lookup(2).size(), 2);
+ EXPECT_EQ(map.lookup(2)[0], 4);
+ EXPECT_EQ(map.lookup(2)[1], 5);
+
+ EXPECT_EQ(map.lookup(3).size(), 1);
+ EXPECT_EQ(map.lookup(3)[0], 6);
+}
+
+TEST(multi_value_map, AddMultiple)
+{
+ MultiValueMap<int, int> map;
+ map.add_multiple(2, {4, 5, 6});
+ map.add_multiple(2, {1, 2});
+ map.add_multiple(5, {7, 5, 3});
+
+ EXPECT_EQ(map.lookup(2).size(), 5);
+ EXPECT_EQ(map.lookup(2)[0], 4);
+ EXPECT_EQ(map.lookup(2)[1], 5);
+ EXPECT_EQ(map.lookup(2)[2], 6);
+ EXPECT_EQ(map.lookup(2)[3], 1);
+ EXPECT_EQ(map.lookup(2)[4], 2);
+
+ EXPECT_EQ(map.lookup(5).size(), 3);
+ EXPECT_EQ(map.lookup(5)[0], 7);
+ EXPECT_EQ(map.lookup(5)[1], 5);
+ EXPECT_EQ(map.lookup(5)[2], 3);
+}
+
+TEST(multi_value_map, Keys)
+{
+ MultiValueMap<int, int> map;
+ map.add(5, 7);
+ map.add(5, 7);
+ map.add_multiple(2, {6, 7, 8});
+
+ Vector<int> keys;
+ for (int key : map.keys()) {
+ keys.append(key);
+ }
+
+ EXPECT_EQ(keys.size(), 2);
+ EXPECT_TRUE(keys.contains(5));
+ EXPECT_TRUE(keys.contains(2));
+}
+
+TEST(multi_value_map, Values)
+{
+ MultiValueMap<int, int> map;
+ map.add(3, 5);
+ map.add_multiple(3, {1, 2});
+ map.add(6, 1);
+
+ Vector<Span<int>> values;
+ for (Span<int> value_span : map.values()) {
+ values.append(value_span);
+ }
+
+ EXPECT_EQ(values.size(), 2);
+}
+
+TEST(multi_value_map, Items)
+{
+ MultiValueMap<int, int> map;
+ map.add_multiple(4, {1, 2, 3});
+
+ for (auto &&item : map.items()) {
+ int key = item.key;
+ Span<int> values = item.value;
+ EXPECT_EQ(key, 4);
+ EXPECT_EQ(values.size(), 3);
+ EXPECT_EQ(values[0], 1);
+ EXPECT_EQ(values[1], 2);
+ EXPECT_EQ(values[2], 3);
+ }
+}
+
+TEST(multi_value_map, UniquePtr)
+{
+ /* Mostly testing if it compiles here. */
+ MultiValueMap<std::unique_ptr<int>, std::unique_ptr<int>> map;
+ map.add(std::make_unique<int>(4), std::make_unique<int>(6));
+ map.add(std::make_unique<int>(4), std::make_unique<int>(7));
+ EXPECT_EQ(map.lookup(std::make_unique<int>(10)).size(), 0);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_set_test.cc b/source/blender/blenlib/tests/BLI_set_test.cc
new file mode 100644
index 00000000000..7bd0b258df8
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_set_test.cc
@@ -0,0 +1,565 @@
+/* Apache License, Version 2.0 */
+
+#include <set>
+#include <unordered_set>
+
+#include "BLI_ghash.h"
+#include "BLI_rand.h"
+#include "BLI_set.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_timeit.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender {
+namespace tests {
+
+TEST(set, DefaultConstructor)
+{
+ Set<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.is_empty());
+}
+
+TEST(set, ContainsNotExistant)
+{
+ Set<int> set;
+ EXPECT_FALSE(set.contains(3));
+}
+
+TEST(set, ContainsExistant)
+{
+ Set<int> set;
+ EXPECT_FALSE(set.contains(5));
+ EXPECT_TRUE(set.is_empty());
+ set.add(5);
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_FALSE(set.is_empty());
+}
+
+TEST(set, AddMany)
+{
+ Set<int> set;
+ for (int i = 0; i < 100; i++) {
+ set.add(i);
+ }
+
+ for (int i = 50; i < 100; i++) {
+ EXPECT_TRUE(set.contains(i));
+ }
+ for (int i = 100; i < 150; i++) {
+ EXPECT_FALSE(set.contains(i));
+ }
+}
+
+TEST(set, InitializerListConstructor)
+{
+ Set<int> set = {4, 5, 6};
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.contains(6));
+ EXPECT_FALSE(set.contains(2));
+ EXPECT_FALSE(set.contains(3));
+}
+
+TEST(set, CopyConstructor)
+{
+ Set<int> set = {3};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+
+ Set<int> set2(set);
+ set2.add(4);
+ EXPECT_TRUE(set2.contains(3));
+ EXPECT_TRUE(set2.contains(4));
+
+ EXPECT_FALSE(set.contains(4));
+}
+
+TEST(set, MoveConstructor)
+{
+ Set<int> set = {1, 2, 3};
+ EXPECT_EQ(set.size(), 3);
+ Set<int> set2(std::move(set));
+ EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(set, CopyAssignment)
+{
+ Set<int> set = {3};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+
+ Set<int> set2;
+ set2 = set;
+ set2.add(4);
+ EXPECT_TRUE(set2.contains(3));
+ EXPECT_TRUE(set2.contains(4));
+
+ EXPECT_FALSE(set.contains(4));
+}
+
+TEST(set, MoveAssignment)
+{
+ Set<int> set = {1, 2, 3};
+ EXPECT_EQ(set.size(), 3);
+ Set<int> set2;
+ set2 = std::move(set);
+ EXPECT_EQ(set.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(set, RemoveContained)
+{
+ Set<int> set = {3, 4, 5};
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(4);
+ EXPECT_TRUE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(3);
+ EXPECT_FALSE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_TRUE(set.contains(5));
+ set.remove_contained(5);
+ EXPECT_FALSE(set.contains(3));
+ EXPECT_FALSE(set.contains(4));
+ EXPECT_FALSE(set.contains(5));
+}
+
+TEST(set, RemoveContainedMany)
+{
+ Set<int> set;
+ for (int i = 0; i < 1000; i++) {
+ set.add(i);
+ }
+ for (int i = 100; i < 1000; i++) {
+ set.remove_contained(i);
+ }
+ for (int i = 900; i < 1000; i++) {
+ set.add(i);
+ }
+
+ for (int i = 0; i < 1000; i++) {
+ if (i < 100 || i >= 900) {
+ EXPECT_TRUE(set.contains(i));
+ }
+ else {
+ EXPECT_FALSE(set.contains(i));
+ }
+ }
+}
+
+TEST(set, Intersects)
+{
+ Set<int> a = {3, 4, 5, 6};
+ Set<int> b = {1, 2, 5};
+ EXPECT_TRUE(Set<int>::Intersects(a, b));
+ EXPECT_FALSE(Set<int>::Disjoint(a, b));
+}
+
+TEST(set, Disjoint)
+{
+ Set<int> a = {5, 6, 7, 8};
+ Set<int> b = {2, 3, 4, 9};
+ EXPECT_FALSE(Set<int>::Intersects(a, b));
+ EXPECT_TRUE(Set<int>::Disjoint(a, b));
+}
+
+TEST(set, AddMultiple)
+{
+ Set<int> a;
+ a.add_multiple({5, 7});
+ EXPECT_TRUE(a.contains(5));
+ EXPECT_TRUE(a.contains(7));
+ EXPECT_FALSE(a.contains(4));
+ a.add_multiple({2, 4, 7});
+ EXPECT_TRUE(a.contains(4));
+ EXPECT_TRUE(a.contains(2));
+ EXPECT_EQ(a.size(), 4);
+}
+
+TEST(set, AddMultipleNew)
+{
+ Set<int> a;
+ a.add_multiple_new({5, 6});
+ EXPECT_TRUE(a.contains(5));
+ EXPECT_TRUE(a.contains(6));
+}
+
+TEST(set, Iterator)
+{
+ Set<int> set = {1, 3, 2, 5, 4};
+ blender::Vector<int> vec;
+ for (int value : set) {
+ vec.append(value);
+ }
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_TRUE(vec.contains(1));
+ EXPECT_TRUE(vec.contains(3));
+ EXPECT_TRUE(vec.contains(2));
+ EXPECT_TRUE(vec.contains(5));
+ EXPECT_TRUE(vec.contains(4));
+}
+
+TEST(set, OftenAddRemoveContained)
+{
+ Set<int> set;
+ for (int i = 0; i < 100; i++) {
+ set.add(42);
+ EXPECT_EQ(set.size(), 1);
+ set.remove_contained(42);
+ EXPECT_EQ(set.size(), 0);
+ }
+}
+
+TEST(set, UniquePtrValues)
+{
+ Set<std::unique_ptr<int>> set;
+ set.add_new(std::unique_ptr<int>(new int()));
+ auto value1 = std::unique_ptr<int>(new int());
+ set.add_new(std::move(value1));
+ set.add(std::unique_ptr<int>(new int()));
+
+ EXPECT_EQ(set.size(), 3);
+}
+
+TEST(set, Clear)
+{
+ Set<int> set = {3, 4, 6, 7};
+ EXPECT_EQ(set.size(), 4);
+ set.clear();
+ EXPECT_EQ(set.size(), 0);
+}
+
+TEST(set, StringSet)
+{
+ Set<std::string> set;
+ set.add("hello");
+ set.add("world");
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_TRUE(set.contains("hello"));
+ EXPECT_TRUE(set.contains("world"));
+ EXPECT_FALSE(set.contains("world2"));
+}
+
+TEST(set, PointerSet)
+{
+ int a, b, c;
+ Set<int *> set;
+ set.add(&a);
+ set.add(&b);
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_TRUE(set.contains(&a));
+ EXPECT_TRUE(set.contains(&b));
+ EXPECT_FALSE(set.contains(&c));
+}
+
+TEST(set, Remove)
+{
+ Set<int> set = {1, 2, 3, 4, 5, 6};
+ EXPECT_EQ(set.size(), 6);
+ EXPECT_TRUE(set.remove(2));
+ EXPECT_EQ(set.size(), 5);
+ EXPECT_FALSE(set.contains(2));
+ EXPECT_FALSE(set.remove(2));
+ EXPECT_EQ(set.size(), 5);
+ EXPECT_TRUE(set.remove(5));
+ EXPECT_EQ(set.size(), 4);
+}
+
+struct Type1 {
+ uint32_t value;
+};
+
+struct Type2 {
+ uint32_t value;
+};
+
+static bool operator==(const Type1 &a, const Type1 &b)
+{
+ return a.value == b.value;
+}
+static bool operator==(const Type2 &a, const Type1 &b)
+{
+ return a.value == b.value;
+}
+
+} // namespace tests
+
+/* This has to be defined in ::blender namespace. */
+template<> struct DefaultHash<tests::Type1> {
+ uint32_t operator()(const tests::Type1 &value) const
+ {
+ return value.value;
+ }
+
+ uint32_t operator()(const tests::Type2 &value) const
+ {
+ return value.value;
+ }
+};
+
+namespace tests {
+
+TEST(set, ContainsAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type1{5}));
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ EXPECT_FALSE(set.contains_as(Type1{6}));
+ EXPECT_FALSE(set.contains_as(Type2{6}));
+}
+
+TEST(set, ContainsAsString)
+{
+ Set<std::string> set;
+ set.add("test");
+ EXPECT_TRUE(set.contains_as("test"));
+ EXPECT_TRUE(set.contains_as(StringRef("test")));
+ EXPECT_FALSE(set.contains_as("string"));
+ EXPECT_FALSE(set.contains_as(StringRef("string")));
+}
+
+TEST(set, RemoveContainedAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_contained_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+}
+
+TEST(set, RemoveAs)
+{
+ Set<Type1> set;
+ set.add(Type1{5});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{6});
+ EXPECT_TRUE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+ set.remove_as(Type2{5});
+ EXPECT_FALSE(set.contains_as(Type2{5}));
+}
+
+TEST(set, AddAs)
+{
+ Set<std::string> set;
+ EXPECT_TRUE(set.add_as("test"));
+ EXPECT_TRUE(set.add_as(StringRef("qwe")));
+ EXPECT_FALSE(set.add_as(StringRef("test")));
+ EXPECT_FALSE(set.add_as("qwe"));
+}
+
+template<uint N> struct EqualityIntModN {
+ bool operator()(uint a, uint b) const
+ {
+ return (a % N) == (b % N);
+ }
+};
+
+template<uint N> struct HashIntModN {
+ uint64_t operator()(uint value) const
+ {
+ return value % N;
+ }
+};
+
+TEST(set, CustomizeHashAndEquality)
+{
+ Set<uint, 0, DefaultProbingStrategy, HashIntModN<10>, EqualityIntModN<10>> set;
+ set.add(4);
+ EXPECT_TRUE(set.contains(4));
+ EXPECT_TRUE(set.contains(14));
+ EXPECT_TRUE(set.contains(104));
+ EXPECT_FALSE(set.contains(5));
+ set.add(55);
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.contains(14));
+ set.remove(1004);
+ EXPECT_FALSE(set.contains(14));
+}
+
+TEST(set, IntrusiveIntKey)
+{
+ Set<int,
+ 2,
+ DefaultProbingStrategy,
+ DefaultHash<int>,
+ DefaultEquality,
+ IntegerSetSlot<int, 100, 200>>
+ set;
+ EXPECT_TRUE(set.add(4));
+ EXPECT_TRUE(set.add(3));
+ EXPECT_TRUE(set.add(11));
+ EXPECT_TRUE(set.add(8));
+ EXPECT_FALSE(set.add(3));
+ EXPECT_FALSE(set.add(4));
+ EXPECT_TRUE(set.remove(4));
+ EXPECT_FALSE(set.remove(7));
+ EXPECT_TRUE(set.add(4));
+ EXPECT_TRUE(set.remove(4));
+}
+
+struct MyKeyType {
+ uint32_t key;
+ int32_t attached_data;
+
+ uint64_t hash() const
+ {
+ return key;
+ }
+
+ friend bool operator==(const MyKeyType &a, const MyKeyType &b)
+ {
+ return a.key == b.key;
+ }
+};
+
+TEST(set, LookupKey)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+ EXPECT_EQ(set.lookup_key({1, 30}).attached_data, 10);
+ EXPECT_EQ(set.lookup_key({2, 0}).attached_data, 20);
+}
+
+TEST(set, LookupKeyDefault)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+
+ MyKeyType fallback{5, 50};
+ EXPECT_EQ(set.lookup_key_default({1, 66}, fallback).attached_data, 10);
+ EXPECT_EQ(set.lookup_key_default({4, 40}, fallback).attached_data, 50);
+}
+
+TEST(set, LookupKeyPtr)
+{
+ Set<MyKeyType> set;
+ set.add({1, 10});
+ set.add({2, 20});
+ EXPECT_EQ(set.lookup_key_ptr({1, 50})->attached_data, 10);
+ EXPECT_EQ(set.lookup_key_ptr({2, 50})->attached_data, 20);
+ EXPECT_EQ(set.lookup_key_ptr({3, 50}), nullptr);
+}
+
+/**
+ * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot.
+ */
+#if 0
+template<typename SetT>
+BLI_NOINLINE void benchmark_random_ints(StringRef name, int amount, int factor)
+{
+ RNG *rng = BLI_rng_new(0);
+ Vector<int> values;
+ for (int i = 0; i < amount; i++) {
+ values.append(BLI_rng_get_int(rng) * factor);
+ }
+ BLI_rng_free(rng);
+
+ SetT set;
+ {
+ SCOPED_TIMER(name + " Add");
+ for (int value : values) {
+ set.add(value);
+ }
+ }
+ int count = 0;
+ {
+ SCOPED_TIMER(name + " Contains");
+ for (int value : values) {
+ count += set.contains(value);
+ }
+ }
+ {
+ SCOPED_TIMER(name + " Remove");
+ for (int value : values) {
+ count += set.remove(value);
+ }
+ }
+
+ /* Print the value for simple error checking and to avoid some compiler optimizations. */
+ std::cout << "Count: " << count << "\n";
+}
+
+TEST(set, Benchmark)
+{
+ for (int i = 0; i < 3; i++) {
+ benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, 1);
+ benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, 1);
+ }
+ std::cout << "\n";
+ for (int i = 0; i < 3; i++) {
+ uint32_t factor = (3 << 10);
+ benchmark_random_ints<blender::Set<int>>("blender::Set ", 100000, factor);
+ benchmark_random_ints<blender::StdUnorderedSetWrapper<int>>("std::unordered_set", 100000, factor);
+ }
+}
+
+/**
+ * Output of the rudimentary benchmark above on my hardware.
+ *
+ * Timer 'blender::Set Add' took 5.5573 ms
+ * Timer 'blender::Set Contains' took 0.807384 ms
+ * Timer 'blender::Set Remove' took 0.953436 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 12.551 ms
+ * Timer 'std::unordered_set Contains' took 2.3323 ms
+ * Timer 'std::unordered_set Remove' took 5.07082 ms
+ * Count: 199998
+ * Timer 'blender::Set Add' took 2.62526 ms
+ * Timer 'blender::Set Contains' took 0.407499 ms
+ * Timer 'blender::Set Remove' took 0.472981 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 6.26945 ms
+ * Timer 'std::unordered_set Contains' took 1.17236 ms
+ * Timer 'std::unordered_set Remove' took 3.77402 ms
+ * Count: 199998
+ * Timer 'blender::Set Add' took 2.59152 ms
+ * Timer 'blender::Set Contains' took 0.415254 ms
+ * Timer 'blender::Set Remove' took 0.477559 ms
+ * Count: 199998
+ * Timer 'std::unordered_set Add' took 6.28129 ms
+ * Timer 'std::unordered_set Contains' took 1.17562 ms
+ * Timer 'std::unordered_set Remove' took 3.77811 ms
+ * Count: 199998
+ *
+ * Timer 'blender::Set Add' took 3.16514 ms
+ * Timer 'blender::Set Contains' took 0.732895 ms
+ * Timer 'blender::Set Remove' took 1.08171 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.57377 ms
+ * Timer 'std::unordered_set Contains' took 1.17008 ms
+ * Timer 'std::unordered_set Remove' took 3.7946 ms
+ * Count: 198790
+ * Timer 'blender::Set Add' took 3.11439 ms
+ * Timer 'blender::Set Contains' took 0.740159 ms
+ * Timer 'blender::Set Remove' took 1.06749 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.35597 ms
+ * Timer 'std::unordered_set Contains' took 1.17713 ms
+ * Timer 'std::unordered_set Remove' took 3.77826 ms
+ * Count: 198790
+ * Timer 'blender::Set Add' took 3.09876 ms
+ * Timer 'blender::Set Contains' took 0.742072 ms
+ * Timer 'blender::Set Remove' took 1.06622 ms
+ * Count: 198790
+ * Timer 'std::unordered_set Add' took 6.4469 ms
+ * Timer 'std::unordered_set Contains' took 1.16515 ms
+ * Timer 'std::unordered_set Remove' took 3.80639 ms
+ * Count: 198790
+ */
+
+#endif /* Benchmark */
+
+} // namespace tests
+} // namespace blender
diff --git a/source/blender/blenlib/tests/BLI_span_test.cc b/source/blender/blenlib/tests/BLI_span_test.cc
new file mode 100644
index 00000000000..587497624f4
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_span_test.cc
@@ -0,0 +1,311 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_span.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(span, FromSmallVector)
+{
+ Vector<int> a = {1, 2, 3};
+ Span<int> a_span = a;
+ EXPECT_EQ(a_span.size(), 3);
+ EXPECT_EQ(a_span[0], 1);
+ EXPECT_EQ(a_span[1], 2);
+ EXPECT_EQ(a_span[2], 3);
+}
+
+TEST(span, AddConstToPointer)
+{
+ int a = 0;
+ std::vector<int *> vec = {&a};
+ Span<int *> span = vec;
+ Span<const int *> const_span = span;
+ EXPECT_EQ(const_span.size(), 1);
+}
+
+TEST(span, IsReferencing)
+{
+ int array[] = {3, 5, 8};
+ MutableSpan<int> span(array, ARRAY_SIZE(array));
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[1], 5);
+ array[1] = 10;
+ EXPECT_EQ(span[1], 10);
+}
+
+TEST(span, DropBack)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_back(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 4);
+ EXPECT_EQ(slice[1], 5);
+}
+
+TEST(span, DropBackAll)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_back(a.size());
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, DropFront)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_front(1);
+ EXPECT_EQ(slice.size(), 3);
+ EXPECT_EQ(slice[0], 5);
+ EXPECT_EQ(slice[1], 6);
+ EXPECT_EQ(slice[2], 7);
+}
+
+TEST(span, DropFrontAll)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).drop_front(a.size());
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, TakeFront)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).take_front(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 4);
+ EXPECT_EQ(slice[1], 5);
+}
+
+TEST(span, TakeBack)
+{
+ Vector<int> a = {5, 6, 7, 8};
+ auto slice = Span<int>(a).take_back(2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 7);
+ EXPECT_EQ(slice[1], 8);
+}
+
+TEST(span, Slice)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).slice(1, 2);
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 5);
+ EXPECT_EQ(slice[1], 6);
+}
+
+TEST(span, SliceEmpty)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ auto slice = Span<int>(a).slice(2, 0);
+ EXPECT_EQ(slice.size(), 0);
+}
+
+TEST(span, SliceRange)
+{
+ Vector<int> a = {1, 2, 3, 4, 5};
+ auto slice = Span<int>(a).slice(IndexRange(2, 2));
+ EXPECT_EQ(slice.size(), 2);
+ EXPECT_EQ(slice[0], 3);
+ EXPECT_EQ(slice[1], 4);
+}
+
+TEST(span, Contains)
+{
+ Vector<int> a = {4, 5, 6, 7};
+ Span<int> a_span = a;
+ EXPECT_TRUE(a_span.contains(4));
+ EXPECT_TRUE(a_span.contains(5));
+ EXPECT_TRUE(a_span.contains(6));
+ EXPECT_TRUE(a_span.contains(7));
+ EXPECT_FALSE(a_span.contains(3));
+ EXPECT_FALSE(a_span.contains(8));
+}
+
+TEST(span, Count)
+{
+ Vector<int> a = {2, 3, 4, 3, 3, 2, 2, 2, 2};
+ Span<int> a_span = a;
+ EXPECT_EQ(a_span.count(1), 0);
+ EXPECT_EQ(a_span.count(2), 5);
+ EXPECT_EQ(a_span.count(3), 3);
+ EXPECT_EQ(a_span.count(4), 1);
+ EXPECT_EQ(a_span.count(5), 0);
+}
+
+static void test_ref_from_initializer_list(Span<int> span)
+{
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_EQ(span[0], 3);
+ EXPECT_EQ(span[1], 6);
+ EXPECT_EQ(span[2], 8);
+ EXPECT_EQ(span[3], 9);
+}
+
+TEST(span, FromInitializerList)
+{
+ test_ref_from_initializer_list({3, 6, 8, 9});
+}
+
+TEST(span, FromVector)
+{
+ std::vector<int> a = {1, 2, 3, 4};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(a_span[0], 1);
+ EXPECT_EQ(a_span[1], 2);
+ EXPECT_EQ(a_span[2], 3);
+ EXPECT_EQ(a_span[3], 4);
+}
+
+TEST(span, FromArray)
+{
+ std::array<int, 2> a = {5, 6};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size(), 2);
+ EXPECT_EQ(a_span[0], 5);
+ EXPECT_EQ(a_span[1], 6);
+}
+
+TEST(span, Fill)
+{
+ std::array<int, 5> a = {4, 5, 6, 7, 8};
+ MutableSpan<int> a_span(a);
+ a_span.fill(1);
+ EXPECT_EQ(a[0], 1);
+ EXPECT_EQ(a[1], 1);
+ EXPECT_EQ(a[2], 1);
+ EXPECT_EQ(a[3], 1);
+ EXPECT_EQ(a[4], 1);
+}
+
+TEST(span, FillIndices)
+{
+ std::array<int, 5> a = {0, 0, 0, 0, 0};
+ MutableSpan<int> a_span(a);
+ a_span.fill_indices({0, 2, 3}, 1);
+ EXPECT_EQ(a[0], 1);
+ EXPECT_EQ(a[1], 0);
+ EXPECT_EQ(a[2], 1);
+ EXPECT_EQ(a[3], 1);
+ EXPECT_EQ(a[4], 0);
+}
+
+TEST(span, SizeInBytes)
+{
+ std::array<int, 10> a;
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.size_in_bytes(), (int64_t)sizeof(a));
+ EXPECT_EQ(a_span.size_in_bytes(), 40);
+}
+
+TEST(span, FirstLast)
+{
+ std::array<int, 4> a = {6, 7, 8, 9};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.first(), 6);
+ EXPECT_EQ(a_span.last(), 9);
+}
+
+TEST(span, FirstLast_OneElement)
+{
+ int a = 3;
+ Span<int> a_span(&a, 1);
+ EXPECT_EQ(a_span.first(), 3);
+ EXPECT_EQ(a_span.last(), 3);
+}
+
+TEST(span, Get)
+{
+ std::array<int, 3> a = {5, 6, 7};
+ Span<int> a_span(a);
+ EXPECT_EQ(a_span.get(0, 42), 5);
+ EXPECT_EQ(a_span.get(1, 42), 6);
+ EXPECT_EQ(a_span.get(2, 42), 7);
+ EXPECT_EQ(a_span.get(3, 42), 42);
+ EXPECT_EQ(a_span.get(4, 42), 42);
+}
+
+TEST(span, ContainsPtr)
+{
+ std::array<int, 3> a = {5, 6, 7};
+ int other = 10;
+ Span<int> a_span(a);
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 0));
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 1));
+ EXPECT_TRUE(a_span.contains_ptr(&a[0] + 2));
+ EXPECT_FALSE(a_span.contains_ptr(&a[0] + 3));
+ EXPECT_FALSE(a_span.contains_ptr(&a[0] - 1));
+ EXPECT_FALSE(a_span.contains_ptr(&other));
+}
+
+TEST(span, FirstIndex)
+{
+ std::array<int, 5> a = {4, 5, 4, 2, 5};
+ Span<int> a_span(a);
+
+ EXPECT_EQ(a_span.first_index(4), 0);
+ EXPECT_EQ(a_span.first_index(5), 1);
+ EXPECT_EQ(a_span.first_index(2), 3);
+}
+
+TEST(span, CastSameSize)
+{
+ int value = 0;
+ std::array<int *, 4> a = {&value, nullptr, nullptr, nullptr};
+ Span<int *> a_span = a;
+ Span<float *> new_a_span = a_span.cast<float *>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 4);
+
+ EXPECT_EQ(a_span[0], &value);
+ EXPECT_EQ(new_a_span[0], (float *)&value);
+}
+
+TEST(span, CastSmallerSize)
+{
+ std::array<uint32_t, 4> a = {3, 4, 5, 6};
+ Span<uint32_t> a_span = a;
+ Span<uint16_t> new_a_span = a_span.cast<uint16_t>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 8);
+}
+
+TEST(span, CastLargerSize)
+{
+ std::array<uint16_t, 4> a = {4, 5, 6, 7};
+ Span<uint16_t> a_span = a;
+ Span<uint32_t> new_a_span = a_span.cast<uint32_t>();
+
+ EXPECT_EQ(a_span.size(), 4);
+ EXPECT_EQ(new_a_span.size(), 2);
+}
+
+TEST(span, VoidPointerSpan)
+{
+ int a;
+ float b;
+ double c;
+
+ auto func1 = [](Span<void *> span) { EXPECT_EQ(span.size(), 3); };
+ func1({&a, &b, &c});
+}
+
+TEST(span, CopyFrom)
+{
+ std::array<int, 4> src = {5, 6, 7, 8};
+ std::array<int, 4> dst = {1, 2, 3, 4};
+
+ EXPECT_EQ(dst[2], 3);
+ MutableSpan(dst).copy_from(src);
+ EXPECT_EQ(dst[0], 5);
+ EXPECT_EQ(dst[1], 6);
+ EXPECT_EQ(dst[2], 7);
+ EXPECT_EQ(dst[3], 8);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_stack_cxx_test.cc b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
new file mode 100644
index 00000000000..3572e751b88
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_stack_cxx_test.cc
@@ -0,0 +1,188 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_stack.hh"
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(stack, DefaultConstructor)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ EXPECT_TRUE(stack.is_empty());
+}
+
+TEST(stack, SpanConstructor)
+{
+ std::array<int, 3> array = {4, 7, 2};
+ Stack<int> stack(array);
+ EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.pop(), 2);
+ EXPECT_EQ(stack.pop(), 7);
+ EXPECT_EQ(stack.pop(), 4);
+ EXPECT_TRUE(stack.is_empty());
+}
+
+TEST(stack, CopyConstructor)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = stack1;
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_FALSE(stack1.is_empty());
+ EXPECT_FALSE(stack2.is_empty());
+ EXPECT_EQ(stack1.pop(), i);
+ EXPECT_EQ(stack2.pop(), i);
+ }
+ EXPECT_TRUE(stack1.is_empty());
+ EXPECT_TRUE(stack2.is_empty());
+}
+
+TEST(stack, MoveConstructor)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = std::move(stack1);
+ EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_EQ(stack2.pop(), i);
+ }
+}
+
+TEST(stack, CopyAssignment)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = {2, 3, 4, 5, 6, 7};
+ stack2 = stack1;
+
+ EXPECT_EQ(stack1.size(), 7);
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_FALSE(stack1.is_empty());
+ EXPECT_FALSE(stack2.is_empty());
+ EXPECT_EQ(stack1.pop(), i);
+ EXPECT_EQ(stack2.pop(), i);
+ }
+ EXPECT_TRUE(stack1.is_empty());
+ EXPECT_TRUE(stack2.is_empty());
+}
+
+TEST(stack, MoveAssignment)
+{
+ Stack<int> stack1 = {1, 2, 3, 4, 5, 6, 7};
+ Stack<int> stack2 = {5, 3, 7, 2, 2};
+ stack2 = std::move(stack1);
+ EXPECT_EQ(stack1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(stack2.size(), 7);
+ for (int i = 7; i >= 1; i--) {
+ EXPECT_EQ(stack2.pop(), i);
+ }
+}
+
+TEST(stack, Push)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ stack.push(3);
+ EXPECT_EQ(stack.size(), 1);
+ stack.push(5);
+ EXPECT_EQ(stack.size(), 2);
+}
+
+TEST(stack, PushMultiple)
+{
+ Stack<int> stack;
+ EXPECT_EQ(stack.size(), 0);
+ stack.push_multiple({1, 2, 3});
+ EXPECT_EQ(stack.size(), 3);
+ EXPECT_EQ(stack.pop(), 3);
+ EXPECT_EQ(stack.pop(), 2);
+ EXPECT_EQ(stack.pop(), 1);
+}
+
+TEST(stack, PushPopMany)
+{
+ Stack<int> stack;
+ for (int i = 0; i < 1000; i++) {
+ stack.push(i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ }
+ for (int i = 999; i > 50; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ }
+ for (int i = 51; i < 5000; i++) {
+ stack.push(i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i + 1));
+ }
+ for (int i = 4999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ EXPECT_EQ(stack.size(), static_cast<unsigned int>(i));
+ }
+}
+
+TEST(stack, PushMultipleAfterPop)
+{
+ Stack<int> stack;
+ for (int i = 0; i < 1000; i++) {
+ stack.push(i);
+ }
+ for (int i = 999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ }
+
+ Vector<int> values;
+ for (int i = 0; i < 5000; i++) {
+ values.append(i);
+ }
+ stack.push_multiple(values);
+ EXPECT_EQ(stack.size(), 5000);
+
+ for (int i = 4999; i >= 0; i--) {
+ EXPECT_EQ(stack.pop(), i);
+ }
+}
+
+TEST(stack, Pop)
+{
+ Stack<int> stack;
+ stack.push(4);
+ stack.push(6);
+ EXPECT_EQ(stack.pop(), 6);
+ EXPECT_EQ(stack.pop(), 4);
+}
+
+TEST(stack, Peek)
+{
+ Stack<int> stack;
+ stack.push(3);
+ stack.push(4);
+ EXPECT_EQ(stack.peek(), 4);
+ EXPECT_EQ(stack.peek(), 4);
+ stack.pop();
+ EXPECT_EQ(stack.peek(), 3);
+}
+
+TEST(stack, UniquePtrValues)
+{
+ Stack<std::unique_ptr<int>> stack;
+ stack.push(std::unique_ptr<int>(new int()));
+ stack.push(std::unique_ptr<int>(new int()));
+ std::unique_ptr<int> a = stack.pop();
+ std::unique_ptr<int> &b = stack.peek();
+ UNUSED_VARS(a, b);
+}
+
+TEST(stack, OveralignedValues)
+{
+ Stack<AlignedBuffer<1, 512>, 2> stack;
+ for (int i = 0; i < 100; i++) {
+ stack.push({});
+ EXPECT_EQ((uintptr_t)&stack.peek() % 512, 0);
+ }
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_string_ref_test.cc b/source/blender/blenlib/tests/BLI_string_ref_test.cc
new file mode 100644
index 00000000000..d08c8a77455
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_string_ref_test.cc
@@ -0,0 +1,277 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_string_ref.hh"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(string_ref_null, DefaultConstructor)
+{
+ StringRefNull ref;
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_EQ(ref[0], '\0');
+}
+
+TEST(string_ref_null, CStringConstructor)
+{
+ const char *str = "Hello";
+ StringRefNull ref(str);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref_null, CStringLengthConstructor)
+{
+ const char *str = "Hello";
+ StringRefNull ref(str, 5);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, DefaultConstructor)
+{
+ StringRef ref;
+ EXPECT_EQ(ref.size(), 0);
+}
+
+TEST(string_ref, StartEndConstructor)
+{
+ const char *text = "hello world";
+ StringRef ref(text, text + 5);
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_TRUE(ref == "hello");
+ EXPECT_FALSE(ref == "hello ");
+}
+
+TEST(string_ref, StartEndConstructorNullptr)
+{
+ StringRef ref(nullptr, nullptr);
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_TRUE(ref == "");
+}
+
+TEST(string_ref, StartEndConstructorSame)
+{
+ const char *text = "hello world";
+ StringRef ref(text, text);
+ EXPECT_EQ(ref.size(), 0);
+ EXPECT_TRUE(ref == "");
+}
+
+TEST(string_ref, CStringConstructor)
+{
+ const char *str = "Test";
+ StringRef ref(str);
+ EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, PointerWithLengthConstructor)
+{
+ const char *str = "Test";
+ StringRef ref(str, 2);
+ EXPECT_EQ(ref.size(), 2);
+ EXPECT_EQ(ref.data(), str);
+}
+
+TEST(string_ref, StdStringConstructor)
+{
+ std::string str = "Test";
+ StringRef ref(str);
+ EXPECT_EQ(ref.size(), 4);
+ EXPECT_EQ(ref.data(), str.data());
+}
+
+TEST(string_ref, SubscriptOperator)
+{
+ StringRef ref("hello");
+ EXPECT_EQ(ref.size(), 5);
+ EXPECT_EQ(ref[0], 'h');
+ EXPECT_EQ(ref[1], 'e');
+ EXPECT_EQ(ref[2], 'l');
+ EXPECT_EQ(ref[3], 'l');
+ EXPECT_EQ(ref[4], 'o');
+}
+
+TEST(string_ref, ToStdString)
+{
+ StringRef ref("test");
+ std::string str = ref;
+ EXPECT_EQ(str.size(), 4);
+ EXPECT_EQ(str, "test");
+}
+
+TEST(string_ref, Print)
+{
+ StringRef ref("test");
+ std::stringstream ss;
+ ss << ref;
+ ss << ref;
+ std::string str = ss.str();
+ EXPECT_EQ(str.size(), 8);
+ EXPECT_EQ(str, "testtest");
+}
+
+TEST(string_ref, Add)
+{
+ StringRef a("qwe");
+ StringRef b("asd");
+ std::string result = a + b;
+ EXPECT_EQ(result, "qweasd");
+}
+
+TEST(string_ref, AddCharPtr1)
+{
+ StringRef ref("test");
+ std::string result = ref + "qwe";
+ EXPECT_EQ(result, "testqwe");
+}
+
+TEST(string_ref, AddCharPtr2)
+{
+ StringRef ref("test");
+ std::string result = "qwe" + ref;
+ EXPECT_EQ(result, "qwetest");
+}
+
+TEST(string_ref, AddString1)
+{
+ StringRef ref("test");
+ std::string result = ref + std::string("asd");
+ EXPECT_EQ(result, "testasd");
+}
+
+TEST(string_ref, AddString2)
+{
+ StringRef ref("test");
+ std::string result = std::string("asd") + ref;
+ EXPECT_EQ(result, "asdtest");
+}
+
+TEST(string_ref, CompareEqual)
+{
+ StringRef ref1("test");
+ StringRef ref2("test");
+ StringRef ref3("other");
+ EXPECT_TRUE(ref1 == ref2);
+ EXPECT_FALSE(ref1 == ref3);
+ EXPECT_TRUE(ref1 != ref3);
+ EXPECT_FALSE(ref1 != ref2);
+}
+
+TEST(string_ref, CompareEqualCharPtr1)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref == "test");
+ EXPECT_FALSE(ref == "other");
+ EXPECT_TRUE(ref != "other");
+ EXPECT_FALSE(ref != "test");
+}
+
+TEST(string_ref, CompareEqualCharPtr2)
+{
+ StringRef ref("test");
+ EXPECT_TRUE("test" == ref);
+ EXPECT_FALSE("other" == ref);
+ EXPECT_TRUE(ref != "other");
+ EXPECT_FALSE(ref != "test");
+}
+
+TEST(string_ref, CompareEqualString1)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref == std::string("test"));
+ EXPECT_FALSE(ref == std::string("other"));
+ EXPECT_TRUE(ref != std::string("other"));
+ EXPECT_FALSE(ref != std::string("test"));
+}
+
+TEST(string_ref, CompareEqualString2)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(std::string("test") == ref);
+ EXPECT_FALSE(std::string("other") == ref);
+ EXPECT_TRUE(std::string("other") != ref);
+ EXPECT_FALSE(std::string("test") != ref);
+}
+
+TEST(string_ref, Iterate)
+{
+ StringRef ref("test");
+ Vector<char> chars;
+ for (char c : ref) {
+ chars.append(c);
+ }
+ EXPECT_EQ(chars.size(), 4);
+ EXPECT_EQ(chars[0], 't');
+ EXPECT_EQ(chars[1], 'e');
+ EXPECT_EQ(chars[2], 's');
+ EXPECT_EQ(chars[3], 't');
+}
+
+TEST(string_ref, StartsWith)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref.startswith(""));
+ EXPECT_TRUE(ref.startswith("t"));
+ EXPECT_TRUE(ref.startswith("te"));
+ EXPECT_TRUE(ref.startswith("tes"));
+ EXPECT_TRUE(ref.startswith("test"));
+ EXPECT_FALSE(ref.startswith("test "));
+ EXPECT_FALSE(ref.startswith("a"));
+}
+
+TEST(string_ref, EndsWith)
+{
+ StringRef ref("test");
+ EXPECT_TRUE(ref.endswith(""));
+ EXPECT_TRUE(ref.endswith("t"));
+ EXPECT_TRUE(ref.endswith("st"));
+ EXPECT_TRUE(ref.endswith("est"));
+ EXPECT_TRUE(ref.endswith("test"));
+ EXPECT_FALSE(ref.endswith(" test"));
+ EXPECT_FALSE(ref.endswith("a"));
+}
+
+TEST(string_ref, DropPrefixN)
+{
+ StringRef ref("test");
+ StringRef ref2 = ref.drop_prefix(2);
+ StringRef ref3 = ref2.drop_prefix(2);
+ EXPECT_EQ(ref2.size(), 2);
+ EXPECT_EQ(ref3.size(), 0);
+ EXPECT_EQ(ref2, "st");
+ EXPECT_EQ(ref3, "");
+}
+
+TEST(string_ref, DropPrefix)
+{
+ StringRef ref("test");
+ StringRef ref2 = ref.drop_prefix("tes");
+ EXPECT_EQ(ref2.size(), 1);
+ EXPECT_EQ(ref2, "t");
+}
+
+TEST(string_ref, Substr)
+{
+ StringRef ref("hello world");
+ EXPECT_EQ(ref.substr(0, 5), "hello");
+ EXPECT_EQ(ref.substr(4, 0), "");
+ EXPECT_EQ(ref.substr(3, 4), "lo w");
+ EXPECT_EQ(ref.substr(6, 5), "world");
+}
+
+TEST(string_ref, Copy)
+{
+ StringRef ref("hello");
+ char dst[10];
+ memset(dst, 0xFF, 10);
+ ref.copy(dst);
+ EXPECT_EQ(dst[5], '\0');
+ EXPECT_EQ(dst[6], 0xFF);
+ EXPECT_EQ(ref, dst);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_vector_set_test.cc b/source/blender/blenlib/tests/BLI_vector_set_test.cc
new file mode 100644
index 00000000000..8f3db8d8403
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_vector_set_test.cc
@@ -0,0 +1,164 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_vector_set.hh"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+TEST(vector_set, DefaultConstructor)
+{
+ VectorSet<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.is_empty());
+}
+
+TEST(vector_set, InitializerListConstructor_WithoutDuplicates)
+{
+ VectorSet<int> set = {1, 4, 5};
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set[0], 1);
+ EXPECT_EQ(set[1], 4);
+ EXPECT_EQ(set[2], 5);
+}
+
+TEST(vector_set, InitializerListConstructor_WithDuplicates)
+{
+ VectorSet<int> set = {1, 3, 3, 2, 1, 5};
+ EXPECT_EQ(set.size(), 4);
+ EXPECT_EQ(set[0], 1);
+ EXPECT_EQ(set[1], 3);
+ EXPECT_EQ(set[2], 2);
+ EXPECT_EQ(set[3], 5);
+}
+
+TEST(vector_set, Copy)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = set1;
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
+}
+
+TEST(vector_set, CopyAssignment)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = {};
+ set2 = set1;
+ EXPECT_EQ(set1.size(), 3);
+ EXPECT_EQ(set2.size(), 3);
+ EXPECT_EQ(set1.index_of(2), 1);
+ EXPECT_EQ(set2.index_of(2), 1);
+}
+
+TEST(vector_set, Move)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = std::move(set1);
+ EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(vector_set, MoveAssignment)
+{
+ VectorSet<int> set1 = {1, 2, 3};
+ VectorSet<int> set2 = {};
+ set2 = std::move(set1);
+ EXPECT_EQ(set1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(set2.size(), 3);
+}
+
+TEST(vector_set, AddNewIncreasesSize)
+{
+ VectorSet<int> set;
+ EXPECT_TRUE(set.is_empty());
+ EXPECT_EQ(set.size(), 0);
+ set.add(5);
+ EXPECT_FALSE(set.is_empty());
+ EXPECT_EQ(set.size(), 1);
+}
+
+TEST(vector_set, AddExistingDoesNotIncreaseSize)
+{
+ VectorSet<int> set;
+ EXPECT_EQ(set.size(), 0);
+ EXPECT_TRUE(set.add(5));
+ EXPECT_EQ(set.size(), 1);
+ EXPECT_FALSE(set.add(5));
+ EXPECT_EQ(set.size(), 1);
+}
+
+TEST(vector_set, Index)
+{
+ VectorSet<int> set = {3, 6, 4};
+ EXPECT_EQ(set.index_of(6), 1);
+ EXPECT_EQ(set.index_of(3), 0);
+ EXPECT_EQ(set.index_of(4), 2);
+}
+
+TEST(vector_set, IndexTry)
+{
+ VectorSet<int> set = {3, 6, 4};
+ EXPECT_EQ(set.index_of_try(5), -1);
+ EXPECT_EQ(set.index_of_try(3), 0);
+ EXPECT_EQ(set.index_of_try(6), 1);
+ EXPECT_EQ(set.index_of_try(2), -1);
+}
+
+TEST(vector_set, RemoveContained)
+{
+ VectorSet<int> set = {4, 5, 6, 7};
+ EXPECT_EQ(set.size(), 4);
+ set.remove_contained(5);
+ EXPECT_EQ(set.size(), 3);
+ EXPECT_EQ(set[0], 4);
+ EXPECT_EQ(set[1], 7);
+ EXPECT_EQ(set[2], 6);
+ set.remove_contained(6);
+ EXPECT_EQ(set.size(), 2);
+ EXPECT_EQ(set[0], 4);
+ EXPECT_EQ(set[1], 7);
+ set.remove_contained(4);
+ EXPECT_EQ(set.size(), 1);
+ EXPECT_EQ(set[0], 7);
+ set.remove_contained(7);
+ EXPECT_EQ(set.size(), 0);
+}
+
+TEST(vector_set, AddMultipleTimes)
+{
+ VectorSet<int> set;
+ for (int i = 0; i < 100; i++) {
+ EXPECT_FALSE(set.contains(i * 13));
+ set.add(i * 12);
+ set.add(i * 13);
+ EXPECT_TRUE(set.contains(i * 13));
+ }
+}
+
+TEST(vector_set, UniquePtrValue)
+{
+ VectorSet<std::unique_ptr<int>> set;
+ set.add_new(std::unique_ptr<int>(new int()));
+ set.add(std::unique_ptr<int>(new int()));
+ set.index_of_try(std::unique_ptr<int>(new int()));
+ std::unique_ptr<int> value = set.pop();
+ UNUSED_VARS(value);
+}
+
+TEST(vector_set, Remove)
+{
+ VectorSet<int> set;
+ EXPECT_TRUE(set.add(5));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_FALSE(set.remove(6));
+ EXPECT_TRUE(set.contains(5));
+ EXPECT_TRUE(set.remove(5));
+ EXPECT_FALSE(set.contains(5));
+ EXPECT_FALSE(set.remove(5));
+ EXPECT_FALSE(set.contains(5));
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenlib/tests/BLI_vector_test.cc b/source/blender/blenlib/tests/BLI_vector_test.cc
new file mode 100644
index 00000000000..f72dfc5deb8
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_vector_test.cc
@@ -0,0 +1,639 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_strict_flags.h"
+#include "BLI_vector.hh"
+#include "testing/testing.h"
+#include <forward_list>
+
+namespace blender::tests {
+
+TEST(vector, DefaultConstructor)
+{
+ Vector<int> vec;
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, SizeConstructor)
+{
+ Vector<int> vec(3);
+ EXPECT_EQ(vec.size(), 3);
+}
+
+/**
+ * Tests that the trivially constructible types are not zero-initialized. We do not want that for
+ * performance reasons.
+ */
+TEST(vector, TrivialTypeSizeConstructor)
+{
+ Vector<char, 1> *vec = new Vector<char, 1>(1);
+ char *ptr = &(*vec)[0];
+ vec->~Vector();
+
+ const char magic = 42;
+ *ptr = magic;
+ EXPECT_EQ(*ptr, magic);
+
+ new (vec) Vector<char, 1>(1);
+ EXPECT_EQ((*vec)[0], magic);
+ EXPECT_EQ(*ptr, magic);
+ delete vec;
+}
+
+TEST(vector, SizeValueConstructor)
+{
+ Vector<int> vec(4, 10);
+ EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec[0], 10);
+ EXPECT_EQ(vec[1], 10);
+ EXPECT_EQ(vec[2], 10);
+ EXPECT_EQ(vec[3], 10);
+}
+
+TEST(vector, InitializerListConstructor)
+{
+ Vector<int> vec = {1, 3, 4, 6};
+ EXPECT_EQ(vec.size(), 4);
+ EXPECT_EQ(vec[0], 1);
+ EXPECT_EQ(vec[1], 3);
+ EXPECT_EQ(vec[2], 4);
+ EXPECT_EQ(vec[3], 6);
+}
+
+TEST(vector, ConvertingConstructor)
+{
+ std::array<float, 5> values = {5.4f, 7.3f, -8.1f, 5.0f, 0.0f};
+ Vector<int> vec = values;
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec[0], 5);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], -8);
+ EXPECT_EQ(vec[3], 5);
+ EXPECT_EQ(vec[4], 0);
+}
+
+struct TestListValue {
+ TestListValue *next, *prev;
+ int value;
+};
+
+TEST(vector, ListBaseConstructor)
+{
+ TestListValue *value1 = new TestListValue{0, 0, 4};
+ TestListValue *value2 = new TestListValue{0, 0, 5};
+ TestListValue *value3 = new TestListValue{0, 0, 6};
+
+ ListBase list = {NULL, NULL};
+ BLI_addtail(&list, value1);
+ BLI_addtail(&list, value2);
+ BLI_addtail(&list, value3);
+ Vector<TestListValue *> vec(list);
+
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0]->value, 4);
+ EXPECT_EQ(vec[1]->value, 5);
+ EXPECT_EQ(vec[2]->value, 6);
+
+ delete value1;
+ delete value2;
+ delete value3;
+}
+
+TEST(vector, ContainerConstructor)
+{
+ std::forward_list<int> list;
+ list.push_front(3);
+ list.push_front(1);
+ list.push_front(5);
+
+ Vector<int> vec = Vector<int>::FromContainer(list);
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 5);
+ EXPECT_EQ(vec[1], 1);
+ EXPECT_EQ(vec[2], 3);
+}
+
+TEST(vector, CopyConstructor)
+{
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2(vec1);
+ EXPECT_EQ(vec2.size(), 3);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+
+ vec1[1] = 5;
+ EXPECT_EQ(vec1[1], 5);
+ EXPECT_EQ(vec2[1], 2);
+}
+
+TEST(vector, CopyConstructor2)
+{
+ Vector<int, 2> vec1 = {1, 2, 3, 4};
+ Vector<int, 3> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, CopyConstructor3)
+{
+ Vector<int, 20> vec1 = {1, 2, 3, 4};
+ Vector<int, 1> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[2], 3);
+}
+
+TEST(vector, CopyConstructor4)
+{
+ Vector<int, 5> vec1 = {1, 2, 3, 4};
+ Vector<int, 6> vec2(vec1);
+
+ EXPECT_EQ(vec1.size(), 4);
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_NE(vec1.data(), vec2.data());
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor)
+{
+ Vector<int> vec1 = {1, 2, 3, 4};
+ Vector<int> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor2)
+{
+ Vector<int, 2> vec1 = {1, 2, 3, 4};
+ Vector<int, 3> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[0], 1);
+ EXPECT_EQ(vec2[1], 2);
+ EXPECT_EQ(vec2[2], 3);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveConstructor3)
+{
+ Vector<int, 20> vec1 = {1, 2, 3, 4};
+ Vector<int, 1> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[2], 3);
+}
+
+TEST(vector, MoveConstructor4)
+{
+ Vector<int, 5> vec1 = {1, 2, 3, 4};
+ Vector<int, 6> vec2(std::move(vec1));
+
+ EXPECT_EQ(vec1.size(), 0); /* NOLINT: bugprone-use-after-move */
+ EXPECT_EQ(vec2.size(), 4);
+ EXPECT_EQ(vec2[3], 4);
+}
+
+TEST(vector, MoveAssignment)
+{
+ Vector<int> vec = {1, 2};
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0], 1);
+ EXPECT_EQ(vec[1], 2);
+
+ vec = Vector<int>({5});
+ EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec[0], 5);
+}
+
+TEST(vector, CopyAssignment)
+{
+ Vector<int> vec1 = {1, 2, 3};
+ Vector<int> vec2 = {4, 5};
+ EXPECT_EQ(vec1.size(), 3);
+ EXPECT_EQ(vec2.size(), 2);
+
+ vec2 = vec1;
+ EXPECT_EQ(vec2.size(), 3);
+
+ vec1[0] = 7;
+ EXPECT_EQ(vec1[0], 7);
+ EXPECT_EQ(vec2[0], 1);
+}
+
+TEST(vector, Append)
+{
+ Vector<int> vec;
+ vec.append(3);
+ vec.append(6);
+ vec.append(7);
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 6);
+ EXPECT_EQ(vec[2], 7);
+}
+
+TEST(vector, AppendAndGetIndex)
+{
+ Vector<int> vec;
+ EXPECT_EQ(vec.append_and_get_index(10), 0);
+ EXPECT_EQ(vec.append_and_get_index(10), 1);
+ EXPECT_EQ(vec.append_and_get_index(10), 2);
+ vec.append(10);
+ EXPECT_EQ(vec.append_and_get_index(10), 4);
+}
+
+TEST(vector, AppendNonDuplicates)
+{
+ Vector<int> vec;
+ vec.append_non_duplicates(4);
+ EXPECT_EQ(vec.size(), 1);
+ vec.append_non_duplicates(5);
+ EXPECT_EQ(vec.size(), 2);
+ vec.append_non_duplicates(4);
+ EXPECT_EQ(vec.size(), 2);
+}
+
+TEST(vector, ExtendNonDuplicates)
+{
+ Vector<int> vec;
+ vec.extend_non_duplicates({1, 2});
+ EXPECT_EQ(vec.size(), 2);
+ vec.extend_non_duplicates({3, 4});
+ EXPECT_EQ(vec.size(), 4);
+ vec.extend_non_duplicates({0, 1, 2, 3});
+ EXPECT_EQ(vec.size(), 5);
+}
+
+TEST(vector, Iterator)
+{
+ Vector<int> vec({1, 4, 9, 16});
+ int i = 1;
+ for (int value : vec) {
+ EXPECT_EQ(value, i * i);
+ i++;
+ }
+}
+
+TEST(vector, BecomeLarge)
+{
+ Vector<int, 4> vec;
+ for (int i = 0; i < 100; i++) {
+ vec.append(i * 5);
+ }
+ EXPECT_EQ(vec.size(), 100);
+ for (int i = 0; i < 100; i++) {
+ EXPECT_EQ(vec[i], static_cast<int>(i * 5));
+ }
+}
+
+static Vector<int> return_by_value_helper()
+{
+ return Vector<int>({3, 5, 1});
+}
+
+TEST(vector, ReturnByValue)
+{
+ Vector<int> vec = return_by_value_helper();
+ EXPECT_EQ(vec.size(), 3);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 5);
+ EXPECT_EQ(vec[2], 1);
+}
+
+TEST(vector, VectorOfVectors_Append)
+{
+ Vector<Vector<int>> vec;
+ EXPECT_EQ(vec.size(), 0);
+
+ Vector<int> v({1, 2});
+ vec.append(v);
+ vec.append({7, 8});
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0][0], 1);
+ EXPECT_EQ(vec[0][1], 2);
+ EXPECT_EQ(vec[1][0], 7);
+ EXPECT_EQ(vec[1][1], 8);
+}
+
+TEST(vector, RemoveLast)
+{
+ Vector<int> vec = {5, 6};
+ EXPECT_EQ(vec.size(), 2);
+ vec.remove_last();
+ EXPECT_EQ(vec.size(), 1);
+ vec.remove_last();
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, IsEmpty)
+{
+ Vector<int> vec;
+ EXPECT_TRUE(vec.is_empty());
+ vec.append(1);
+ EXPECT_FALSE(vec.is_empty());
+ vec.remove_last();
+ EXPECT_TRUE(vec.is_empty());
+}
+
+TEST(vector, RemoveReorder)
+{
+ Vector<int> vec = {4, 5, 6, 7};
+ vec.remove_and_reorder(1);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], 6);
+ vec.remove_and_reorder(2);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ vec.remove_and_reorder(0);
+ EXPECT_EQ(vec[0], 7);
+ vec.remove_and_reorder(0);
+ EXPECT_TRUE(vec.is_empty());
+}
+
+TEST(vector, RemoveFirstOccurrenceAndReorder)
+{
+ Vector<int> vec = {4, 5, 6, 7};
+ vec.remove_first_occurrence_and_reorder(5);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ EXPECT_EQ(vec[2], 6);
+ vec.remove_first_occurrence_and_reorder(6);
+ EXPECT_EQ(vec[0], 4);
+ EXPECT_EQ(vec[1], 7);
+ vec.remove_first_occurrence_and_reorder(4);
+ EXPECT_EQ(vec[0], 7);
+ vec.remove_first_occurrence_and_reorder(7);
+ EXPECT_EQ(vec.size(), 0);
+}
+
+TEST(vector, Remove)
+{
+ Vector<int> vec = {1, 2, 3, 4, 5, 6};
+ vec.remove(3);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({1, 2, 3, 5, 6}).begin()));
+ vec.remove(0);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5, 6}).begin()));
+ vec.remove(3);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 3, 5}).begin()));
+ vec.remove(1);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2, 5}).begin()));
+ vec.remove(1);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({2}).begin()));
+ vec.remove(0);
+ EXPECT_TRUE(std::equal(vec.begin(), vec.end(), Span<int>({}).begin()));
+}
+
+TEST(vector, ExtendSmallVector)
+{
+ Vector<int> a = {2, 3, 4};
+ Vector<int> b = {11, 12};
+ b.extend(a);
+ EXPECT_EQ(b.size(), 5);
+ EXPECT_EQ(b[0], 11);
+ EXPECT_EQ(b[1], 12);
+ EXPECT_EQ(b[2], 2);
+ EXPECT_EQ(b[3], 3);
+ EXPECT_EQ(b[4], 4);
+}
+
+TEST(vector, ExtendArray)
+{
+ int array[] = {3, 4, 5, 6};
+
+ Vector<int> a;
+ a.extend(array, 2);
+
+ EXPECT_EQ(a.size(), 2);
+ EXPECT_EQ(a[0], 3);
+ EXPECT_EQ(a[1], 4);
+}
+
+TEST(vector, Last)
+{
+ Vector<int> a{3, 5, 7};
+ EXPECT_EQ(a.last(), 7);
+}
+
+TEST(vector, AppendNTimes)
+{
+ Vector<int> a;
+ a.append_n_times(5, 3);
+ a.append_n_times(2, 2);
+ EXPECT_EQ(a.size(), 5);
+ EXPECT_EQ(a[0], 5);
+ EXPECT_EQ(a[1], 5);
+ EXPECT_EQ(a[2], 5);
+ EXPECT_EQ(a[3], 2);
+ EXPECT_EQ(a[4], 2);
+}
+
+TEST(vector, UniquePtrValue)
+{
+ Vector<std::unique_ptr<int>> vec;
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ vec.append(std::unique_ptr<int>(new int()));
+ EXPECT_EQ(vec.size(), 4);
+
+ std::unique_ptr<int> &a = vec.last();
+ std::unique_ptr<int> b = vec.pop_last();
+ vec.remove_and_reorder(0);
+ vec.remove(0);
+ EXPECT_EQ(vec.size(), 1);
+
+ UNUSED_VARS(a, b);
+}
+
+class TypeConstructMock {
+ public:
+ bool default_constructed = false;
+ bool copy_constructed = false;
+ bool move_constructed = false;
+ bool copy_assigned = false;
+ bool move_assigned = false;
+
+ TypeConstructMock() : default_constructed(true)
+ {
+ }
+
+ TypeConstructMock(const TypeConstructMock &UNUSED(other)) : copy_constructed(true)
+ {
+ }
+
+ TypeConstructMock(TypeConstructMock &&UNUSED(other)) noexcept : move_constructed(true)
+ {
+ }
+
+ TypeConstructMock &operator=(const TypeConstructMock &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ copy_assigned = true;
+ return *this;
+ }
+
+ TypeConstructMock &operator=(TypeConstructMock &&other) noexcept
+ {
+ if (this == &other) {
+ return *this;
+ }
+
+ move_assigned = true;
+ return *this;
+ }
+};
+
+TEST(vector, SizeConstructorCallsDefaultConstructor)
+{
+ Vector<TypeConstructMock> vec(3);
+ EXPECT_TRUE(vec[0].default_constructed);
+ EXPECT_TRUE(vec[1].default_constructed);
+ EXPECT_TRUE(vec[2].default_constructed);
+}
+
+TEST(vector, SizeValueConstructorCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec(3, TypeConstructMock());
+ EXPECT_TRUE(vec[0].copy_constructed);
+ EXPECT_TRUE(vec[1].copy_constructed);
+ EXPECT_TRUE(vec[2].copy_constructed);
+}
+
+TEST(vector, AppendCallsCopyConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ TypeConstructMock value;
+ vec.append(value);
+ EXPECT_TRUE(vec[0].copy_constructed);
+}
+
+TEST(vector, AppendCallsMoveConstructor)
+{
+ Vector<TypeConstructMock> vec;
+ vec.append(TypeConstructMock());
+ EXPECT_TRUE(vec[0].move_constructed);
+}
+
+TEST(vector, SmallVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, LargeVectorCopyCallsCopyConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(src);
+ EXPECT_TRUE(dst[0].copy_constructed);
+ EXPECT_TRUE(dst[1].copy_constructed);
+}
+
+TEST(vector, SmallVectorMoveCallsMoveConstructor)
+{
+ Vector<TypeConstructMock, 2> src(2);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+ EXPECT_TRUE(dst[0].move_constructed);
+ EXPECT_TRUE(dst[1].move_constructed);
+}
+
+TEST(vector, LargeVectorMoveCallsNoConstructor)
+{
+ Vector<TypeConstructMock, 2> src(5);
+ Vector<TypeConstructMock, 2> dst(std::move(src));
+
+ EXPECT_TRUE(dst[0].default_constructed);
+ EXPECT_FALSE(dst[0].move_constructed);
+ EXPECT_FALSE(dst[0].copy_constructed);
+}
+
+TEST(vector, Resize)
+{
+ std::string long_string = "012345678901234567890123456789";
+ Vector<std::string> vec;
+ EXPECT_EQ(vec.size(), 0);
+ vec.resize(2);
+ EXPECT_EQ(vec.size(), 2);
+ EXPECT_EQ(vec[0], "");
+ EXPECT_EQ(vec[1], "");
+ vec.resize(5, long_string);
+ EXPECT_EQ(vec.size(), 5);
+ EXPECT_EQ(vec[0], "");
+ EXPECT_EQ(vec[1], "");
+ EXPECT_EQ(vec[2], long_string);
+ EXPECT_EQ(vec[3], long_string);
+ EXPECT_EQ(vec[4], long_string);
+ vec.resize(1);
+ EXPECT_EQ(vec.size(), 1);
+ EXPECT_EQ(vec[0], "");
+}
+
+TEST(vector, FirstIndexOf)
+{
+ Vector<int> vec = {2, 3, 5, 7, 5, 9};
+ EXPECT_EQ(vec.first_index_of(2), 0);
+ EXPECT_EQ(vec.first_index_of(5), 2);
+ EXPECT_EQ(vec.first_index_of(9), 5);
+}
+
+TEST(vector, FirstIndexTryOf)
+{
+ Vector<int> vec = {2, 3, 5, 7, 5, 9};
+ EXPECT_EQ(vec.first_index_of_try(2), 0);
+ EXPECT_EQ(vec.first_index_of_try(4), -1);
+ EXPECT_EQ(vec.first_index_of_try(5), 2);
+ EXPECT_EQ(vec.first_index_of_try(9), 5);
+ EXPECT_EQ(vec.first_index_of_try(1), -1);
+}
+
+TEST(vector, OveralignedValues)
+{
+ Vector<AlignedBuffer<1, 512>, 2> vec;
+ for (int i = 0; i < 100; i++) {
+ vec.append({});
+ EXPECT_EQ((uintptr_t)&vec.last() % 512, 0);
+ }
+}
+
+TEST(vector, ConstructVoidPointerVector)
+{
+ int a;
+ float b;
+ double c;
+ Vector<void *> vec = {&a, &b, &c};
+ EXPECT_EQ(vec.size(), 3);
+}
+
+TEST(vector, Fill)
+{
+ Vector<int> vec(5);
+ vec.fill(3);
+ EXPECT_EQ(vec.size(), 5u);
+ EXPECT_EQ(vec[0], 3);
+ EXPECT_EQ(vec[1], 3);
+ EXPECT_EQ(vec[2], 3);
+ EXPECT_EQ(vec[3], 3);
+ EXPECT_EQ(vec[4], 3);
+}
+
+} // namespace blender::tests
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index cb2094d050f..888863dda06 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -102,28 +102,27 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
if (bhead->code == ENDB) {
break;
}
- else {
- const short *sp = fd->filesdna->structs[bhead->SDNAnr];
- const char *name = fd->filesdna->types[sp[0]];
- char buf[4];
-
- buf[0] = (bhead->code >> 24) & 0xFF;
- buf[1] = (bhead->code >> 16) & 0xFF;
- buf[2] = (bhead->code >> 8) & 0xFF;
- buf[3] = (bhead->code >> 0) & 0xFF;
-
- buf[0] = buf[0] ? buf[0] : ' ';
- buf[1] = buf[1] ? buf[1] : ' ';
- buf[2] = buf[2] ? buf[2] : ' ';
- buf[3] = buf[3] ? buf[3] : ' ';
-
- fprintf(fp,
- "['%.4s', '%s', %d, %ld ],\n",
- buf,
- name,
- bhead->nr,
- (long int)(bhead->len + sizeof(BHead)));
- }
+
+ const short *sp = fd->filesdna->structs[bhead->SDNAnr];
+ const char *name = fd->filesdna->types[sp[0]];
+ char buf[4];
+
+ buf[0] = (bhead->code >> 24) & 0xFF;
+ buf[1] = (bhead->code >> 16) & 0xFF;
+ buf[2] = (bhead->code >> 8) & 0xFF;
+ buf[3] = (bhead->code >> 0) & 0xFF;
+
+ buf[0] = buf[0] ? buf[0] : ' ';
+ buf[1] = buf[1] ? buf[1] : ' ';
+ buf[2] = buf[2] ? buf[2] : ' ';
+ buf[3] = buf[3] ? buf[3] : ' ';
+
+ fprintf(fp,
+ "['%.4s', '%s', %d, %ld ],\n",
+ buf,
+ name,
+ bhead->nr,
+ (long int)(bhead->len + sizeof(BHead)));
}
fprintf(fp, "]\n");
}
@@ -268,7 +267,7 @@ LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh)
if (bhead->code == ENDB) {
break;
}
- else if (BKE_idtype_idcode_is_valid(bhead->code)) {
+ if (BKE_idtype_idcode_is_valid(bhead->code)) {
if (BKE_idtype_idcode_is_linkable(bhead->code)) {
const char *str = BKE_idtype_idcode_to_name(bhead->code);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 134e23d36e8..dc2eda7686b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -373,7 +373,7 @@ static void oldnewmap_insert_or_replace(OldNewMap *onm, OldNew entry)
onm->nentries++;
break;
}
- else if (onm->entries[index].oldp == entry.oldp) {
+ if (onm->entries[index].oldp == entry.oldp) {
onm->entries[index] = entry;
break;
}
@@ -1112,9 +1112,8 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
return true;
}
- else {
- return false;
- }
+
+ return false;
}
else if (bhead->code == ENDB) {
break;
@@ -1156,7 +1155,7 @@ static int *read_file_thumbnail(FileData *fd)
blend_thumb = data;
break;
}
- else if (bhead->code != REND) {
+ if (bhead->code != REND) {
/* Thumbnail is stored in TEST immediately after first REND... */
break;
}
@@ -1373,9 +1372,8 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
errno ? strerror(errno) : TIP_("insufficient content"));
return NULL;
}
- else {
- BLI_lseek(file, 0, SEEK_SET);
- }
+
+ BLI_lseek(file, 0, SEEK_SET);
/* Regular file. */
if (memcmp(header, "BLENDER", sizeof(header)) == 0) {
@@ -1397,12 +1395,11 @@ static FileData *blo_filedata_from_file_descriptor(const char *filepath,
errno ? strerror(errno) : TIP_("unknown error reading file"));
return NULL;
}
- else {
- /* 'seek_fn' is too slow for gzip, don't set it. */
- read_fn = fd_read_gzip_from_file;
- /* Caller must close. */
- file = -1;
- }
+
+ /* 'seek_fn' is too slow for gzip, don't set it. */
+ read_fn = fd_read_gzip_from_file;
+ /* Caller must close. */
+ file = -1;
}
if (read_fn == NULL) {
@@ -1487,7 +1484,7 @@ static int fd_read_gzip_from_memory(FileData *filedata,
if (err == Z_STREAM_END) {
return 0;
}
- else if (err != Z_OK) {
+ if (err != Z_OK) {
printf("fd_read_gzip_from_memory: zlib error\n");
return 0;
}
@@ -1521,28 +1518,27 @@ FileData *blo_filedata_from_memory(const void *mem, int memsize, ReportList *rep
BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read") : TIP_("Unable to open"));
return NULL;
}
- else {
- FileData *fd = filedata_new();
- const char *cp = mem;
- fd->buffer = mem;
- fd->buffersize = memsize;
+ FileData *fd = filedata_new();
+ const char *cp = mem;
- /* test if gzip */
- if (cp[0] == 0x1f && cp[1] == 0x8b) {
- if (0 == fd_read_gzip_from_memory_init(fd)) {
- blo_filedata_free(fd);
- return NULL;
- }
- }
- else {
- fd->read = fd_read_from_memory;
+ fd->buffer = mem;
+ fd->buffersize = memsize;
+
+ /* test if gzip */
+ if (cp[0] == 0x1f && cp[1] == 0x8b) {
+ if (0 == fd_read_gzip_from_memory_init(fd)) {
+ blo_filedata_free(fd);
+ return NULL;
}
+ }
+ else {
+ fd->read = fd_read_from_memory;
+ }
- fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+ fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
- return blo_decode_and_check(fd, reports);
- }
+ return blo_decode_and_check(fd, reports);
}
FileData *blo_filedata_from_memfile(MemFile *memfile,
@@ -1553,16 +1549,15 @@ FileData *blo_filedata_from_memfile(MemFile *memfile,
BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>");
return NULL;
}
- else {
- FileData *fd = filedata_new();
- fd->memfile = memfile;
- fd->undo_direction = params->undo_direction;
- fd->read = fd_read_from_memfile;
- fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+ FileData *fd = filedata_new();
+ fd->memfile = memfile;
+ fd->undo_direction = params->undo_direction;
- return blo_decode_and_check(fd, reports);
- }
+ fd->read = fd_read_from_memfile;
+ fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
+
+ return blo_decode_and_check(fd, reports);
}
void blo_filedata_free(FileData *fd)
@@ -1695,7 +1690,7 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha
if (BLO_has_bfile_extension(r_dir) && BLI_is_file(r_dir)) {
break;
}
- else if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
+ if (STREQ(r_dir, BLO_EMBEDDED_STARTUP_BLEND)) {
break;
}
@@ -4162,7 +4157,7 @@ static void direct_link_curve(BlendDataReader *reader, Curve *cu)
direct_link_animdata(reader, cu->adt);
/* Protect against integer overflow vulnerability. */
- CLAMP(cu->len_wchar, 0, INT_MAX - 4);
+ CLAMP(cu->len_char32, 0, INT_MAX - 4);
BLO_read_pointer_array(reader, (void **)&cu->mat);
@@ -5518,7 +5513,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
/* initialize the curve. Maybe this could be moved to modififer logic */
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Thick) {
@@ -5527,7 +5522,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_thickness);
if (gpmd->curve_thickness) {
BKE_curvemapping_blend_read(reader, gpmd->curve_thickness);
- BKE_curvemapping_initialize(gpmd->curve_thickness);
+ BKE_curvemapping_init(gpmd->curve_thickness);
}
}
else if (md->type == eGpencilModifierType_Tint) {
@@ -5536,7 +5531,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Smooth) {
@@ -5544,7 +5539,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Color) {
@@ -5552,7 +5547,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
else if (md->type == eGpencilModifierType_Opacity) {
@@ -5560,7 +5555,7 @@ static void direct_link_gpencil_modifiers(BlendDataReader *reader, ListBase *lb)
BLO_read_data_address(reader, &gpmd->curve_intensity);
if (gpmd->curve_intensity) {
BKE_curvemapping_blend_read(reader, gpmd->curve_intensity);
- BKE_curvemapping_initialize(gpmd->curve_intensity);
+ BKE_curvemapping_init(gpmd->curve_intensity);
}
}
}
@@ -8695,9 +8690,8 @@ static void direct_link_volume(BlendDataReader *reader, Volume *volume)
static void lib_link_simulation(BlendLibReader *reader, Simulation *simulation)
{
- LISTBASE_FOREACH (
- PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
- BLO_read_id_address(reader, simulation->id.lib, &handle_item->id);
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_read_id_address(reader, simulation->id.lib, &dependency->id);
}
}
@@ -8716,7 +8710,7 @@ static void direct_link_simulation(BlendDataReader *reader, Simulation *simulati
}
}
- BLO_read_list(reader, &simulation->persistent_data_handles);
+ BLO_read_list(reader, &simulation->dependencies);
}
/** \} */
@@ -9254,17 +9248,16 @@ static bool read_libblock_undo_restore(
*r_id_old = id_old;
return true;
}
- else if (id_old != NULL) {
+ if (id_old != NULL) {
/* Local datablock was changed. Restore at the address of the old datablock. */
DEBUG_PRINTF("read to old existing address\n");
*r_id_old = id_old;
return false;
}
- else {
- /* Local datablock does not exist in the undo step, so read from scratch. */
- DEBUG_PRINTF("read at new address\n");
- return false;
- }
+
+ /* Local datablock does not exist in the undo step, so read from scratch. */
+ DEBUG_PRINTF("read at new address\n");
+ return false;
}
/* This routine reads a datablock and its direct data, and advances bhead to
@@ -10035,7 +10028,7 @@ static int verg_bheadsort(const void *v1, const void *v2)
if (x1->old > x2->old) {
return 1;
}
- else if (x1->old < x2->old) {
+ if (x1->old < x2->old) {
return -1;
}
return 0;
@@ -11125,9 +11118,8 @@ static void expand_simulation(BlendExpander *expander, Simulation *simulation)
if (simulation->adt) {
expand_animdata(expander, simulation->adt);
}
- LISTBASE_FOREACH (
- PersistentDataHandleItem *, handle_item, &simulation->persistent_data_handles) {
- BLO_expand(expander, handle_item->id);
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ BLO_expand(expander, dependency->id);
}
}
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 3ed59a0baa1..bef37bdd960 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -280,7 +280,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.keepzoom |= (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_KEEPASPECT);
region->v2d.keeptot = V2D_KEEPTOT_STRICT;
region->v2d.minzoom = region->v2d.maxzoom = 1.0f;
- // region->v2d.flag |= V2D_IS_INITIALISED;
+ // region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_GRAPH: {
@@ -297,7 +297,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.max[0] = MAXFRAMEF;
region->v2d.max[1] = FLT_MAX;
- // region->v2d.flag |= V2D_IS_INITIALISED;
+ // region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_NLA: {
@@ -355,7 +355,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb)
region->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES);
region->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_VERTICAL_HANDLES);
region->v2d.align = V2D_ALIGN_NO_NEG_Y;
- region->v2d.flag |= V2D_IS_INITIALISED;
+ region->v2d.flag |= V2D_IS_INIT;
break;
}
case SPACE_NODE: {
@@ -635,6 +635,7 @@ static void do_versions_socket_default_value_259(bNodeSocket *sock)
}
}
+/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -965,7 +966,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
bPoseChannel *pchan;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- /* just need to initialise rotation axis properly... */
+ /* Just need to initialize rotation axis properly. */
pchan->rotAxis[1] = 1.0f;
}
}
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index b3bf8991c3e..3f24a7f14ca 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -658,6 +658,7 @@ static void do_versions_nodetree_customnodes(bNodeTree *ntree, int UNUSED(is_gro
}
}
+/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
if (bmain->versionfile < 260) {
@@ -1205,7 +1206,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (region->regiontype == RGN_TYPE_PREVIEW) {
if (region->alignment != RGN_ALIGN_NONE) {
region->flag |= RGN_FLAG_HIDDEN;
- region->v2d.flag &= ~V2D_IS_INITIALISED;
+ region->v2d.flag &= ~V2D_IS_INIT;
region->alignment = RGN_ALIGN_NONE;
hide = true;
@@ -2520,7 +2521,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (cu = bmain->curves.first; cu; cu = cu->id.next) {
if (cu->str) {
- cu->len_wchar = BLI_strlen_utf8(cu->str);
+ cu->len_char32 = BLI_strlen_utf8(cu->str);
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 521fc4b9b82..b19c6221391 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -242,7 +242,7 @@ static void do_version_action_editor_properties_region(ListBase *regionbase)
/* already exists */
return;
}
- else if (region->regiontype == RGN_TYPE_WINDOW) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
/* add new region here */
ARegion *arnew = MEM_callocN(sizeof(ARegion), "buttons for action");
@@ -377,9 +377,8 @@ static char *replace_bbone_easing_rnapath(char *old_path)
MEM_freeN(old_path);
return new_path;
}
- else {
- return old_path;
- }
+
+ return old_path;
}
static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id),
@@ -421,6 +420,7 @@ static void do_version_bbone_easing_fcurve_fix(ID *UNUSED(id),
}
}
+/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
if (!MAIN_VERSION_ATLEAST(bmain, 270, 0)) {
@@ -1108,7 +1108,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) {
CurveMapping *curve_mapping = &scene->r.mblur_shutter_curve;
BKE_curvemapping_set_defaults(curve_mapping, 1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(curve_mapping);
+ BKE_curvemapping_init(curve_mapping);
BKE_curvemap_reset(
curve_mapping->cm, &curve_mapping->clipr, CURVE_PRESET_MAX, CURVEMAP_SLOPE_POS_NEG);
}
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 111ac728cc3..7add20431ad 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -190,7 +190,7 @@ static void do_version_workspaces_create_from_screens(Main *bmain)
static void do_version_area_change_space_to_space_action(ScrArea *area, const Scene *scene)
{
SpaceType *stype = BKE_spacetype_from_id(SPACE_ACTION);
- SpaceAction *saction = (SpaceAction *)stype->new (area, scene);
+ SpaceAction *saction = (SpaceAction *)stype->create(area, scene);
ARegion *region_channels;
/* Properly free current regions */
@@ -1792,6 +1792,7 @@ static void do_versions_seq_set_cache_defaults(Editing *ed)
ed->recycle_max_cost = 10.0f;
}
+/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
{
bool use_collection_compat_28 = true;
@@ -1958,7 +1959,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt;
if ((gset) && (gset->cur_falloff == NULL)) {
gset->cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(gset->cur_falloff);
+ BKE_curvemapping_init(gset->cur_falloff);
BKE_curvemap_reset(gset->cur_falloff->cm,
&gset->cur_falloff->clipr,
CURVE_PRESET_GAUSS,
@@ -3371,7 +3372,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
GP_Sculpt_Settings *gset = &scene->toolsettings->gp_sculpt;
if ((gset) && (gset->cur_primitive == NULL)) {
gset->cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
- BKE_curvemapping_initialize(gset->cur_primitive);
+ BKE_curvemapping_init(gset->cur_primitive);
BKE_curvemap_reset(gset->cur_primitive->cm,
&gset->cur_primitive->clipr,
CURVE_PRESET_BELL,
@@ -4767,7 +4768,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4778,7 +4779,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4788,7 +4789,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4798,7 +4799,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
@@ -4808,7 +4809,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (mmd->curve_intensity == NULL) {
mmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (mmd->curve_intensity) {
- BKE_curvemapping_initialize(mmd->curve_intensity);
+ BKE_curvemapping_init(mmd->curve_intensity);
}
}
break;
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index a96b82e2e91..12b5a297df5 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -22,9 +22,11 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
+#include "DNA_cachefile_types.h"
#include "DNA_constraint_types.h"
#include "DNA_genfile.h"
#include "DNA_gpencil_modifier_types.h"
@@ -446,5 +448,39 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
+
+ /* Initialise additional velocity parameter for CacheFiles. */
+ if (!DNA_struct_elem_find(
+ fd->filesdna, "MeshSeqCacheModifierData", "float", "velocity_scale")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_MeshSequenceCache) {
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md;
+ mcmd->velocity_scale = 1.0f;
+ mcmd->vertex_velocities = NULL;
+ mcmd->num_vertices = 0;
+ }
+ }
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "CacheFile", "char", "velocity_unit")) {
+ for (CacheFile *cache_file = bmain->cachefiles.first; cache_file != NULL;
+ cache_file = cache_file->id.next) {
+ BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name));
+ cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "int", "viewport_resolution")) {
+ for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) {
+ LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
+ if (md->type == eModifierType_Ocean) {
+ OceanModifierData *omd = (OceanModifierData *)md;
+ omd->viewport_resolution = omd->resolution;
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c
index 46faddf6e5a..26329fca6fa 100644
--- a/source/blender/blenloader/intern/versioning_cycles.c
+++ b/source/blender/blenloader/intern/versioning_cycles.c
@@ -1447,7 +1447,7 @@ void do_versions_after_linking_cycles(Main *bmain)
if (is_fstop) {
continue;
}
- else if (aperture_size > 0.0f) {
+ if (aperture_size > 0.0f) {
if (camera->type == CAM_ORTHO) {
camera->dof.aperture_fstop = 1.0f / (2.0f * aperture_size);
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 7f75c0100b8..ae6d3a58091 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -106,7 +106,7 @@ static void blo_update_defaults_screen(bScreen *screen,
/* Some toolbars have been saved as initialized,
* we don't want them to have odd zoom-level or scrolling set, see: T47047 */
if (ELEM(region->regiontype, RGN_TYPE_UI, RGN_TYPE_TOOLS, RGN_TYPE_TOOL_PROPS)) {
- region->v2d.flag &= ~V2D_IS_INITIALISED;
+ region->v2d.flag &= ~V2D_IS_INIT;
}
}
@@ -326,7 +326,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (ts->gp_sculpt.cur_falloff == NULL) {
ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(gp_falloff_curve->cm,
&gp_falloff_curve->clipr,
CURVE_PRESET_GAUSS,
@@ -335,7 +335,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (ts->gp_sculpt.cur_primitive == NULL) {
ts->gp_sculpt.cur_primitive = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_primitive_curve = ts->gp_sculpt.cur_primitive;
- BKE_curvemapping_initialize(gp_primitive_curve);
+ BKE_curvemapping_init(gp_primitive_curve);
BKE_curvemap_reset(gp_primitive_curve->cm,
&gp_primitive_curve->clipr,
CURVE_PRESET_BELL,
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 44c7c35e47d..fa72e2a147d 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -493,6 +493,7 @@ void blo_do_version_old_trackto_to_constraints(Object *ob)
ob->track = NULL;
}
+/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
@@ -2096,7 +2097,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
if (la->curfalloff == NULL) {
la->curfalloff = BKE_curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f);
- BKE_curvemapping_initialize(la->curfalloff);
+ BKE_curvemapping_init(la->curfalloff);
}
}
}
diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c
index 50e3b375166..e2dc27d7e88 100644
--- a/source/blender/blenloader/intern/versioning_userdef.c
+++ b/source/blender/blenloader/intern/versioning_userdef.c
@@ -366,7 +366,7 @@ void BLO_version_defaults_userpref_blend(Main *bmain, UserDef *userdef)
}
if (!USER_VERSION_ATLEAST(250, 0)) {
/* adjust grease-pencil distances */
- userdef->gp_manhattendist = 1;
+ userdef->gp_manhattandist = 1;
userdef->gp_euclideandist = 2;
/* adjust default interpolation for new IPO-curves */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 0d1c3f2c3e5..a393b4e07b7 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -240,9 +240,8 @@ static bool ww_open_none(WriteWrap *ww, const char *filepath)
FILE_HANDLE(ww) = file;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool ww_close_none(WriteWrap *ww)
{
@@ -267,9 +266,8 @@ static bool ww_open_zlib(WriteWrap *ww, const char *filepath)
FILE_HANDLE(ww) = file;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static bool ww_close_zlib(WriteWrap *ww)
{
@@ -2007,7 +2005,7 @@ static void write_curve(BlendWriter *writer, Curve *cu, const void *id_address)
if (cu->vfont) {
BLO_write_raw(writer, cu->len + 1, cu->str);
- BLO_write_struct_array(writer, CharInfo, cu->len_wchar + 1, cu->strinfo);
+ BLO_write_struct_array(writer, CharInfo, cu->len_char32 + 1, cu->strinfo);
BLO_write_struct_array(writer, TextBox, cu->totbox, cu->tb);
}
else {
@@ -3867,7 +3865,7 @@ static void write_simulation(BlendWriter *writer, Simulation *simulation, const
}
}
- BLO_write_struct_list(writer, PersistentDataHandleItem, &simulation->persistent_data_handles);
+ BLO_write_struct_list(writer, SimulationDependency, &simulation->dependencies);
}
}
@@ -4052,8 +4050,9 @@ static bool write_file_handle(Main *mainvar,
* avoid thumbnail detecting changes because of this. */
mywrite_flush(wd);
- OverrideLibraryStorage *override_storage =
- wd->use_memfile ? NULL : BKE_lib_override_library_operations_store_initialize();
+ OverrideLibraryStorage *override_storage = wd->use_memfile ?
+ NULL :
+ BKE_lib_override_library_operations_store_init();
#define ID_BUFFER_STATIC_SIZE 8192
/* This outer loop allows to save first data-blocks from real mainvar,
diff --git a/source/blender/blentranslation/intern/blt_translation.c b/source/blender/blentranslation/intern/blt_translation.c
index 0ca068d4263..00118bc72e6 100644
--- a/source/blender/blentranslation/intern/blt_translation.c
+++ b/source/blender/blentranslation/intern/blt_translation.c
@@ -120,9 +120,9 @@ const char *BLT_translate_do(const char *msgctxt, const char *msgid)
if (BLT_translate()) {
return BLT_pgettext(msgctxt, msgid);
}
- else {
- return msgid;
- }
+
+ return msgid;
+
#else
(void)msgctxt;
return msgid;
@@ -135,9 +135,9 @@ const char *BLT_translate_do_iface(const char *msgctxt, const char *msgid)
if (BLT_translate_iface()) {
return BLT_pgettext(msgctxt, msgid);
}
- else {
- return msgid;
- }
+
+ return msgid;
+
#else
(void)msgctxt;
return msgid;
@@ -150,9 +150,9 @@ const char *BLT_translate_do_tooltip(const char *msgctxt, const char *msgid)
if (BLT_translate_tooltips()) {
return BLT_pgettext(msgctxt, msgid);
}
- else {
- return msgid;
- }
+
+ return msgid;
+
#else
(void)msgctxt;
return msgid;
@@ -165,9 +165,9 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid
if (BLT_translate_new_dataname()) {
return BLT_pgettext(msgctxt, msgid);
}
- else {
- return msgid;
- }
+
+ return msgid;
+
#else
(void)msgctxt;
return msgid;
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index e8298f4dffc..256ef55ac59 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -295,7 +295,7 @@ static bool quad_co(const float v1[3],
float r_uv[2])
{
float projverts[5][3], n2[3];
- float origin[2] = {0.0f, 0.0f};
+ const float origin[2] = {0.0f, 0.0f};
int i;
/* project points into 2d along normal */
@@ -328,7 +328,7 @@ static bool quad_co(const float v1[3],
return true;
}
-static void mdisp_axis_from_quad(float v1[3],
+static void mdisp_axis_from_quad(const float v1[3],
const float v2[3],
float UNUSED(v3[3]),
const float v4[3],
diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c
index 80634618f6f..a9d1972bd7e 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -179,13 +179,12 @@ BMLoop *BM_loop_other_vert_loop_by_edge(BMLoop *l, BMEdge *e)
if (l->e == e) {
return l->next;
}
- else if (l->prev->e == e) {
+ if (l->prev->e == e) {
return l->prev;
}
- else {
- BLI_assert(0);
- return NULL;
- }
+
+ BLI_assert(0);
+ return NULL;
}
/**
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 6c666183755..8b814240a42 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -45,6 +45,11 @@
#include "./intern/bmesh_private.h"
+// #define BEVEL_DEBUG_TIME
+#ifdef BEVEL_DEBUG_TIME
+# include "PIL_time.h"
+#endif
+
#define BEVEL_EPSILON_D 1e-6
#define BEVEL_EPSILON 1e-6f
#define BEVEL_EPSILON_SQ 1e-12f
@@ -917,7 +922,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
* segment (and its continuation into vmesh) can usually arbitrarily be
* the previous face or the next face.
* Or, for the center polygon of a corner, all of the faces around
- * the vertex are possible choices.
+ * the vertex are possibleface_component choices.
* If we just choose randomly, the resulting UV maps or material
* assignment can look ugly/inconsistent.
* Allow for the case when arguments are null.
@@ -1147,7 +1152,8 @@ static int edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v)
/* co should be approximately on the plane between e1 and e2, which share common vert v and common
* face f (which cannot be NULL). Is it between those edges, sweeping CCW? */
-static bool point_between_edges(float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2)
+static bool point_between_edges(
+ const float co[3], BMVert *v, BMFace *f, EdgeHalf *e1, EdgeHalf *e2)
{
BMVert *v1, *v2;
float dir1[3], dir2[3], dirco[3], no[3];
@@ -1891,6 +1897,59 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns
}
/**
+ * Helper for #calculate_profile that builds the 3D locations for the segments
+ * and the higher power of 2 segments.
+ */
+static void calculate_profile_segments(const Profile *profile,
+ const float map[4][4],
+ const bool use_map,
+ const bool reversed,
+ const int ns,
+ const double *xvals,
+ const double *yvals,
+ float *r_prof_co)
+{
+ /* Iterate over the vertices along the boundary arc. */
+ for (int k = 0; k <= ns; k++) {
+ float co[3];
+ if (k == 0) {
+ copy_v3_v3(co, profile->start);
+ }
+ else if (k == ns) {
+ copy_v3_v3(co, profile->end);
+ }
+ else {
+ if (use_map) {
+ const float p[3] = {
+ reversed ? (float)yvals[ns - k] : (float)xvals[k],
+ reversed ? (float)xvals[ns - k] : (float)yvals[k],
+ 0.0f,
+ };
+ /* Do the 2D->3D transformation of the profile coordinates. */
+ mul_v3_m4v3(co, map, p);
+ }
+ else {
+ interp_v3_v3v3(co, profile->start, profile->end, (float)k / (float)ns);
+ }
+ }
+ /* Finish the 2D->3D transformation by projecting onto the final profile plane. */
+ float *prof_co_k = r_prof_co + 3 * k;
+ if (!is_zero_v3(profile->proj_dir)) {
+ float co2[3];
+ add_v3_v3v3(co2, co, profile->proj_dir);
+ /* pro->plane_co and pro->plane_no are filled in #set_profile_params. */
+ if (!isect_line_plane_v3(prof_co_k, co, co2, profile->plane_co, profile->plane_no)) {
+ /* Shouldn't happen. */
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+ else {
+ copy_v3_v3(prof_co_k, co);
+ }
+ }
+}
+
+/**
* Calculate the actual coordinate values for bndv's profile.
* This is only needed if bp->seg > 1.
* Allocate the space for them if that hasn't been done already.
@@ -1900,12 +1959,6 @@ static void get_profile_point(BevelParams *bp, const Profile *pro, int i, int ns
*/
static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, bool miter)
{
- int i, k, ns;
- const double *xvals, *yvals;
- float co[3], co2[3], p[3], map[4][4], bottom_corner[3], top_corner[3];
- float *prof_co, *prof_co_k;
- float r;
- bool need_2, map_ok;
Profile *pro = &bndv->profile;
ProfileSpacing *pro_spacing = (miter) ? &bp->pro_spacing_miter : &bp->pro_spacing;
@@ -1913,89 +1966,51 @@ static void calculate_profile(BevelParams *bp, BoundVert *bndv, bool reversed, b
return;
}
- need_2 = bp->seg != bp->pro_spacing.seg_2;
- if (!pro->prof_co) {
- pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena,
- ((size_t)bp->seg + 1) * 3 * sizeof(float));
+ bool need_2 = bp->seg != bp->pro_spacing.seg_2;
+ if (pro->prof_co == NULL) {
+ pro->prof_co = (float *)BLI_memarena_alloc(bp->mem_arena, sizeof(float) * 3 * (bp->seg + 1));
if (need_2) {
pro->prof_co_2 = (float *)BLI_memarena_alloc(
- bp->mem_arena, ((size_t)bp->pro_spacing.seg_2 + 1) * 3 * sizeof(float));
+ bp->mem_arena, sizeof(float) * 3 * (bp->pro_spacing.seg_2 + 1));
}
else {
pro->prof_co_2 = pro->prof_co;
}
}
- r = pro->super_r;
- if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && r == PRO_LINE_R) {
- map_ok = false;
+
+ bool use_map;
+ float map[4][4];
+ if (bp->profile_type == BEVEL_PROFILE_SUPERELLIPSE && pro->super_r == PRO_LINE_R) {
+ use_map = false;
}
else {
- map_ok = make_unit_square_map(pro->start, pro->middle, pro->end, map);
+ use_map = make_unit_square_map(pro->start, pro->middle, pro->end, map);
}
- if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && map_ok) {
+ if (bp->vmesh_method == BEVEL_VMESH_CUTOFF && use_map) {
/* Calculate the "height" of the profile by putting the (0,0) and (1,1) corners of the
* un-transformed profile through the 2D->3D map and calculating the distance between them. */
- zero_v3(p);
- mul_v3_m4v3(bottom_corner, map, p);
- p[0] = 1.0f;
- p[1] = 1.0f;
- mul_v3_m4v3(top_corner, map, p);
+ float bottom_corner[3] = {0.0f, 0.0f, 0.0f};
+ mul_v3_m4v3(bottom_corner, map, bottom_corner);
+ float top_corner[3] = {1.0f, 1.0f, 0.0f};
+ mul_v3_m4v3(top_corner, map, top_corner);
+
pro->height = len_v3v3(bottom_corner, top_corner);
}
- /* The first iteration is the nseg case, the second is the seg_2 case (if it's needed) .*/
- for (i = 0; i < 2; i++) {
- if (i == 0) {
- ns = bp->seg;
- xvals = pro_spacing->xvals;
- yvals = pro_spacing->yvals;
- prof_co = pro->prof_co;
- }
- else {
- if (!need_2) {
- break; /* Shares coords with pro->prof_co. */
- }
- ns = bp->pro_spacing.seg_2;
- xvals = pro_spacing->xvals_2;
- yvals = pro_spacing->yvals_2;
- prof_co = pro->prof_co_2;
- }
-
- /* Iterate over the vertices along the boundary arc. */
- for (k = 0; k <= ns; k++) {
- if (k == 0) {
- copy_v3_v3(co, pro->start);
- }
- else if (k == ns) {
- copy_v3_v3(co, pro->end);
- }
- else {
- if (map_ok) {
- p[0] = reversed ? (float)yvals[ns - k] : (float)xvals[k];
- p[1] = reversed ? (float)xvals[ns - k] : (float)yvals[k];
- p[2] = 0.0f;
- /* Do the 2D->3D transformation of the profile coordinates. */
- mul_v3_m4v3(co, map, p);
- }
- else {
- interp_v3_v3v3(co, pro->start, pro->end, (float)k / (float)ns);
- }
- }
- /* Finish the 2D->3D transformation by projecting onto the final profile plane. */
- prof_co_k = prof_co + 3 * k; /* Each coord takes up 3 spaces. */
- if (!is_zero_v3(pro->proj_dir)) {
- add_v3_v3v3(co2, co, pro->proj_dir);
- /* pro->plane_co and pro->plane_no are filled in "set_profile_params". */
- if (!isect_line_plane_v3(prof_co_k, co, co2, pro->plane_co, pro->plane_no)) {
- /* Shouldn't happen. */
- copy_v3_v3(prof_co_k, co);
- }
- }
- else {
- copy_v3_v3(prof_co_k, co);
- }
- }
+ /* Calculate the 3D locations for the profile points */
+ calculate_profile_segments(
+ pro, map, use_map, reversed, bp->seg, pro_spacing->xvals, pro_spacing->yvals, pro->prof_co);
+ /* Also calcualte for the is the seg_2 case if it's needed .*/
+ if (need_2) {
+ calculate_profile_segments(pro,
+ map,
+ use_map,
+ reversed,
+ bp->pro_spacing.seg_2,
+ pro_spacing->xvals_2,
+ pro_spacing->yvals_2,
+ pro->prof_co_2);
}
}
@@ -4843,7 +4858,7 @@ static void build_square_in_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv, VMesh
/**
* Copy whichever of \a a and \a b is closer to v into \a r.
*/
-static void closer_v3_v3v3v3(float r[3], float a[3], float b[3], float v[3])
+static void closer_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float v[3])
{
if (len_squared_v3v3(a, v) <= len_squared_v3v3(b, v)) {
copy_v3_v3(r, a);
@@ -7143,68 +7158,64 @@ static float find_profile_fullness(BevelParams *bp)
*/
static void set_profile_spacing(BevelParams *bp, ProfileSpacing *pro_spacing, bool custom)
{
- int seg, seg_2;
+ int seg = bp->seg;
- seg = bp->seg;
- seg_2 = power_of_2_max_i(bp->seg);
- if (seg > 1) {
- /* Sample the seg_2 segments used for subdividing the vertex meshes. */
- if (seg_2 == 2) {
- seg_2 = 4;
- }
- bp->pro_spacing.seg_2 = seg_2;
- if (seg_2 == seg) {
- pro_spacing->xvals_2 = pro_spacing->xvals;
- pro_spacing->yvals_2 = pro_spacing->yvals;
- }
- else {
- pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg_2 + 1) * sizeof(double));
- pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg_2 + 1) * sizeof(double));
- if (custom) {
- /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */
- BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg_2);
-
- /* Copy segment locations into the profile spacing struct. */
- for (int i = 0; i < seg_2 + 1; i++) {
- pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y;
- pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x;
- }
- }
- else {
- find_even_superellipse_chords(
- seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2);
- }
- }
+ if (seg <= 1) {
+ /* Only 1 segment, we don't need any profile information. */
+ pro_spacing->xvals = NULL;
+ pro_spacing->yvals = NULL;
+ pro_spacing->xvals_2 = NULL;
+ pro_spacing->yvals_2 = NULL;
+ pro_spacing->seg_2 = 0;
+ return;
+ }
- /* Sample the input number of segments. */
- pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg + 1) * sizeof(double));
- pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena,
- (size_t)(seg + 1) * sizeof(double));
+ int seg_2 = max_ii(power_of_2_max_i(bp->seg), 4);
+
+ /* Sample the seg_2 segments used during vertex mesh subdivision. */
+ bp->pro_spacing.seg_2 = seg_2;
+ if (seg_2 == seg) {
+ pro_spacing->xvals_2 = pro_spacing->xvals;
+ pro_spacing->yvals_2 = pro_spacing->yvals;
+ }
+ else {
+ pro_spacing->xvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
+ sizeof(double) * (seg_2 + 1));
+ pro_spacing->yvals_2 = (double *)BLI_memarena_alloc(bp->mem_arena,
+ sizeof(double) * (seg_2 + 1));
if (custom) {
- /* Make sure the curve profile's sample table is full. */
- if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) {
- BKE_curveprofile_initialize((CurveProfile *)bp->custom_profile, (short)seg);
- }
+ /* Make sure the curve profile widget's sample table is full of the seg_2 samples. */
+ BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg_2);
/* Copy segment locations into the profile spacing struct. */
- for (int i = 0; i < seg + 1; i++) {
- pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y;
- pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x;
+ for (int i = 0; i < seg_2 + 1; i++) {
+ pro_spacing->xvals_2[i] = (double)bp->custom_profile->segments[i].y;
+ pro_spacing->yvals_2[i] = (double)bp->custom_profile->segments[i].x;
}
}
else {
- find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals);
+ find_even_superellipse_chords(
+ seg_2, bp->pro_super_r, pro_spacing->xvals_2, pro_spacing->yvals_2);
}
}
- else { /* Only 1 segment, we don't need any profile information. */
- pro_spacing->xvals = NULL;
- pro_spacing->yvals = NULL;
- pro_spacing->xvals_2 = NULL;
- pro_spacing->yvals_2 = NULL;
- pro_spacing->seg_2 = 0;
+
+ /* Sample the input number of segments. */
+ pro_spacing->xvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1));
+ pro_spacing->yvals = (double *)BLI_memarena_alloc(bp->mem_arena, sizeof(double) * (seg + 1));
+ if (custom) {
+ /* Make sure the curve profile's sample table is full. */
+ if (bp->custom_profile->segments_len != seg || !bp->custom_profile->segments) {
+ BKE_curveprofile_init((CurveProfile *)bp->custom_profile, (short)seg);
+ }
+
+ /* Copy segment locations into the profile spacing struct. */
+ for (int i = 0; i < seg + 1; i++) {
+ pro_spacing->xvals[i] = (double)bp->custom_profile->segments[i].y;
+ pro_spacing->yvals[i] = (double)bp->custom_profile->segments[i].x;
+ }
+ }
+ else {
+ find_even_superellipse_chords(seg, bp->pro_super_r, pro_spacing->xvals, pro_spacing->yvals);
}
}
@@ -7493,6 +7504,10 @@ void BM_mesh_bevel(BMesh *bm,
bp.custom_profile = custom_profile;
bp.vmesh_method = vmesh_method;
+#ifdef BEVEL_DEBUG_TIME
+ double start_time = PIL_check_seconds_timer();
+#endif
+
/* Disable the miters with the cutoff vertex mesh method, the combination isn't useful anyway. */
if (bp.vmesh_method == BEVEL_VMESH_CUTOFF) {
bp.miter_outer = BEVEL_MITER_SHARP;
@@ -7661,4 +7676,8 @@ void BM_mesh_bevel(BMesh *bm,
BLI_ghash_free(bp.face_hash, NULL, NULL);
BLI_memarena_free(bp.mem_arena);
}
+#ifdef BEVEL_DEBUG_TIME
+ double end_time = PIL_check_seconds_timer();
+ printf("BMESH BEVEL TIME = %.3f\n", end_time - start_time);
+#endif
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 3ed27ea580e..94a578fe1d7 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -171,7 +171,10 @@ static float bm_edge_calc_dissolve_error(const BMEdge *e,
#ifdef USE_DEGENERATE_CHECK
-static void mul_v2_m3v3_center(float r[2], float m[3][3], const float a[3], const float center[3])
+static void mul_v2_m3v3_center(float r[2],
+ const float m[3][3],
+ const float a[3],
+ const float center[3])
{
BLI_assert(r != a);
BLI_assert(r != center);
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 6426fe9c687..371d8d59d6c 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -898,7 +898,7 @@ static int isect_bvhtree_point_v3(BVHTree *tree, const float **looptris, const f
&z_buffer,
};
BVHTreeRayHit hit = {0};
- float dir[3] = {1.0f, 0.0f, 0.0f};
+ const float dir[3] = {1.0f, 0.0f, 0.0f};
/* Need to initialize hit even tho it's not used.
* This is to make it so kd-tree believes we didn't intersect anything and
diff --git a/source/blender/bmesh/tools/bmesh_intersect_edges.c b/source/blender/bmesh/tools/bmesh_intersect_edges.c
index 52231033fd3..5e266fdac0e 100644
--- a/source/blender/bmesh/tools/bmesh_intersect_edges.c
+++ b/source/blender/bmesh/tools/bmesh_intersect_edges.c
@@ -455,7 +455,7 @@ static void bm_elemxelem_bvhtree_overlap(const BVHTree *tree1,
int parallel_tasks_num = BLI_bvhtree_overlap_thread_num(tree1);
for (int i = 0; i < parallel_tasks_num; i++) {
if (pair_stack[i] == NULL) {
- pair_stack[i] = BLI_stack_new(sizeof(struct EDBMSplitElem[2]), __func__);
+ pair_stack[i] = BLI_stack_new(sizeof(const struct EDBMSplitElem[2]), __func__);
}
}
data->pair_stack = pair_stack;
diff --git a/source/blender/compositor/intern/COM_CompositorContext.cpp b/source/blender/compositor/intern/COM_CompositorContext.cpp
index e572fe7c99e..3d55fcba086 100644
--- a/source/blender/compositor/intern/COM_CompositorContext.cpp
+++ b/source/blender/compositor/intern/COM_CompositorContext.cpp
@@ -36,7 +36,6 @@ int CompositorContext::getFramenumber() const
if (this->m_rd) {
return this->m_rd->cfra;
}
- else {
- return -1; /* this should never happen */
- }
+
+ return -1; /* this should never happen */
}
diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp
index edfeb3a3a04..60676ee42b7 100644
--- a/source/blender/compositor/intern/COM_Converter.cpp
+++ b/source/blender/compositor/intern/COM_Converter.cpp
@@ -416,19 +416,19 @@ NodeOperation *Converter::convertDataType(NodeOperationOutput *from, NodeOperati
if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_COLOR) {
return new ConvertValueToColorOperation();
}
- else if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
+ if (fromDatatype == COM_DT_VALUE && toDatatype == COM_DT_VECTOR) {
return new ConvertValueToVectorOperation();
}
- else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
+ if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VALUE) {
return new ConvertColorToValueOperation();
}
- else if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
+ if (fromDatatype == COM_DT_COLOR && toDatatype == COM_DT_VECTOR) {
return new ConvertColorToVectorOperation();
}
- else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
+ if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_VALUE) {
return new ConvertVectorToValueOperation();
}
- else if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
+ if (fromDatatype == COM_DT_VECTOR && toDatatype == COM_DT_COLOR) {
return new ConvertVectorToColorOperation();
}
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
index b958314d1b4..f58d7a768cc 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp
@@ -136,10 +136,9 @@ float MemoryBuffer::getMaximumValue(rcti *rect)
delete temp;
return result;
}
- else {
- BLI_assert(0);
- return 0.0f;
- }
+
+ BLI_assert(0);
+ return 0.0f;
}
MemoryBuffer::~MemoryBuffer()
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cpp b/source/blender/compositor/intern/COM_NodeOperation.cpp
index fa4b5a07c65..4e3c5d2df6c 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cpp
+++ b/source/blender/compositor/intern/COM_NodeOperation.cpp
@@ -145,9 +145,8 @@ NodeOperation *NodeOperation::getInputOperation(unsigned int inputSocketIndex)
if (input && input->isConnected()) {
return &input->getLink()->getOperation();
}
- else {
- return NULL;
- }
+
+ return NULL;
}
void NodeOperation::getConnectedInputSockets(Inputs *sockets)
@@ -168,30 +167,29 @@ bool NodeOperation::determineDependingAreaOfInterest(rcti *input,
BLI_rcti_init(output, input->xmin, input->xmax, input->ymin, input->ymax);
return false;
}
- else {
- rcti tempOutput;
- bool first = true;
- for (int i = 0; i < getNumberOfInputSockets(); i++) {
- NodeOperation *inputOperation = this->getInputOperation(i);
- if (inputOperation &&
- inputOperation->determineDependingAreaOfInterest(input, readOperation, &tempOutput)) {
- if (first) {
- output->xmin = tempOutput.xmin;
- output->ymin = tempOutput.ymin;
- output->xmax = tempOutput.xmax;
- output->ymax = tempOutput.ymax;
- first = false;
- }
- else {
- output->xmin = min(output->xmin, tempOutput.xmin);
- output->ymin = min(output->ymin, tempOutput.ymin);
- output->xmax = max(output->xmax, tempOutput.xmax);
- output->ymax = max(output->ymax, tempOutput.ymax);
- }
+
+ rcti tempOutput;
+ bool first = true;
+ for (int i = 0; i < getNumberOfInputSockets(); i++) {
+ NodeOperation *inputOperation = this->getInputOperation(i);
+ if (inputOperation &&
+ inputOperation->determineDependingAreaOfInterest(input, readOperation, &tempOutput)) {
+ if (first) {
+ output->xmin = tempOutput.xmin;
+ output->ymin = tempOutput.ymin;
+ output->xmax = tempOutput.xmax;
+ output->ymax = tempOutput.ymax;
+ first = false;
+ }
+ else {
+ output->xmin = min(output->xmin, tempOutput.xmin);
+ output->ymin = min(output->ymin, tempOutput.ymin);
+ output->xmax = max(output->xmax, tempOutput.xmax);
+ output->ymax = max(output->ymax, tempOutput.ymax);
}
}
- return !first;
}
+ return !first;
}
/*****************
@@ -210,9 +208,8 @@ SocketReader *NodeOperationInput::getReader()
if (isConnected()) {
return &m_link->getOperation();
}
- else {
- return NULL;
- }
+
+ return NULL;
}
void NodeOperationInput::determineResolution(unsigned int resolution[2],
diff --git a/source/blender/compositor/nodes/COM_TimeNode.cpp b/source/blender/compositor/nodes/COM_TimeNode.cpp
index 9722ead0716..247e0d11df6 100644
--- a/source/blender/compositor/nodes/COM_TimeNode.cpp
+++ b/source/blender/compositor/nodes/COM_TimeNode.cpp
@@ -49,7 +49,7 @@ void TimeNode::convertToOperations(NodeConverter &converter,
fac = (context.getFramenumber() - node->custom1) / (float)(node->custom2 - node->custom1);
}
- BKE_curvemapping_initialize((CurveMapping *)node->storage);
+ BKE_curvemapping_init((CurveMapping *)node->storage);
fac = BKE_curvemapping_evaluateF((CurveMapping *)node->storage, 0, fac);
operation->setValue(clamp_f(fac, 0.0f, 1.0f));
converter.addOperation(operation);
diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
index 85725cc1d37..2c762323104 100644
--- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
+++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp
@@ -105,9 +105,9 @@ static int extrapolate9(float *E0,
}
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
+
#undef PEQ
#undef PCPY
}
diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
index 66043abd951..50f8eab5fbc 100644
--- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
+++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
@@ -39,9 +39,8 @@ float ConvertDepthToRadiusOperation::determineFocalDistance()
this->m_cam_lens = camera->lens;
return BKE_camera_object_dof_distance(this->m_cameraObject);
}
- else {
- return 10.0f;
- }
+
+ return 10.0f;
}
void ConvertDepthToRadiusOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
index b18e77cf0e3..855f728f7bf 100644
--- a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp
@@ -35,7 +35,7 @@ CurveBaseOperation::~CurveBaseOperation()
void CurveBaseOperation::initExecution()
{
- BKE_curvemapping_initialize(this->m_curveMapping);
+ BKE_curvemapping_init(this->m_curveMapping);
}
void CurveBaseOperation::deinitExecution()
{
diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp
index d9a59002caf..202e614c0c5 100644
--- a/source/blender/compositor/operations/COM_DenoiseOperation.cpp
+++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp
@@ -73,14 +73,13 @@ bool DenoiseOperation::determineDependingAreaOfInterest(rcti * /*input*/,
if (isCached()) {
return false;
}
- else {
- rcti newInput;
- newInput.xmax = this->getWidth();
- newInput.xmin = 0;
- newInput.ymax = this->getHeight();
- newInput.ymin = 0;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
- }
+
+ rcti newInput;
+ newInput.xmax = this->getWidth();
+ newInput.xmin = 0;
+ newInput.ymax = this->getHeight();
+ newInput.ymin = 0;
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
void DenoiseOperation::generateDenoise(float *data,
diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
index b775bfdee4c..73790447216 100644
--- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp
+++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp
@@ -74,13 +74,12 @@ bool DisplaceOperation::read_displacement(
r_v = 0.0f;
return false;
}
- else {
- float col[4];
- m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR);
- r_u = origin[0] - col[0] * xscale;
- r_v = origin[1] - col[1] * yscale;
- return true;
- }
+
+ float col[4];
+ m_inputVectorProgram->readSampled(col, x, y, COM_PS_BILINEAR);
+ r_u = origin[0] - col[0] * xscale;
+ r_v = origin[1] - col[1] * yscale;
+ return true;
}
void DisplaceOperation::pixelTransform(const float xy[2], float r_uv[2], float r_deriv[2][2])
diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
index 84f7fe2d225..675a402de6f 100644
--- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
+++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
@@ -1330,9 +1330,8 @@ bool DoubleEdgeMaskOperation::determineDependingAreaOfInterest(rcti * /*input*/,
newInput.ymin = 0;
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
- else {
- return false;
- }
+
+ return false;
}
void DoubleEdgeMaskOperation::initExecution()
diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
index 7a6b69d12fa..0ccb959712f 100644
--- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
@@ -47,18 +47,17 @@ bool FastGaussianBlurOperation::determineDependingAreaOfInterest(
if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
return true;
}
- else {
- if (this->m_iirgaus) {
- return false;
- }
- else {
- newInput.xmin = 0;
- newInput.ymin = 0;
- newInput.xmax = this->getWidth();
- newInput.ymax = this->getHeight();
- }
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+
+ if (this->m_iirgaus) {
+ return false;
}
+
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
void FastGaussianBlurOperation::initExecution()
@@ -282,12 +281,12 @@ bool FastGaussianBlurValueOperation::determineDependingAreaOfInterest(
if (this->m_iirgaus) {
return false;
}
- else {
- newInput.xmin = 0;
- newInput.ymin = 0;
- newInput.xmax = this->getWidth();
- newInput.ymax = this->getHeight();
- }
+
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
diff --git a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
index 43e571c4bb7..dd479da864c 100644
--- a/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
@@ -176,23 +176,22 @@ bool GaussianBokehBlurOperation::determineDependingAreaOfInterest(
if (operation->determineDependingAreaOfInterest(&sizeInput, readOperation, output)) {
return true;
}
+
+ if (this->m_sizeavailable && this->m_gausstab != NULL) {
+ newInput.xmin = 0;
+ newInput.ymin = 0;
+ newInput.xmax = this->getWidth();
+ newInput.ymax = this->getHeight();
+ }
else {
- if (this->m_sizeavailable && this->m_gausstab != NULL) {
- newInput.xmin = 0;
- newInput.ymin = 0;
- newInput.xmax = this->getWidth();
- newInput.ymax = this->getHeight();
- }
- else {
- int addx = this->m_radx;
- int addy = this->m_rady;
- newInput.xmax = input->xmax + addx;
- newInput.xmin = input->xmin - addx;
- newInput.ymax = input->ymax + addy;
- newInput.ymin = input->ymin - addy;
- }
- return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ int addx = this->m_radx;
+ int addy = this->m_rady;
+ newInput.xmax = input->xmax + addx;
+ newInput.xmin = input->xmin - addx;
+ newInput.ymax = input->ymax + addy;
+ newInput.ymin = input->ymin - addy;
}
+ return BlurBaseOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// reference image
@@ -351,13 +350,12 @@ bool GaussianBlurReferenceOperation::determineDependingAreaOfInterest(
if (operation->determineDependingAreaOfInterest(input, readOperation, output)) {
return true;
}
- else {
- int addx = this->m_data.sizex + 2;
- int addy = this->m_data.sizey + 2;
- newInput.xmax = input->xmax + addx;
- newInput.xmin = input->xmin - addx;
- newInput.ymax = input->ymax + addy;
- newInput.ymin = input->ymin - addy;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
- }
+
+ int addx = this->m_data.sizex + 2;
+ int addy = this->m_data.sizey + 2;
+ newInput.xmax = input->xmax + addx;
+ newInput.xmin = input->xmin - addx;
+ newInput.ymax = input->ymax + addy;
+ newInput.ymin = input->ymin - addy;
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
index 593f1eaeefa..278e65a7dfd 100644
--- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp
@@ -58,12 +58,11 @@ bool GlareBaseOperation::determineDependingAreaOfInterest(rcti * /*input*/,
if (isCached()) {
return false;
}
- else {
- rcti newInput;
- newInput.xmax = this->getWidth();
- newInput.xmin = 0;
- newInput.ymax = this->getHeight();
- newInput.ymin = 0;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
- }
+
+ rcti newInput;
+ newInput.xmax = this->getWidth();
+ newInput.xmin = 0;
+ newInput.ymax = this->getHeight();
+ newInput.ymin = 0;
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
index 9f01cf5d63a..760b833d1e1 100644
--- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp
@@ -28,9 +28,8 @@ static float smoothMask(float x, float y)
if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) {
return t;
}
- else {
- return 0.0f;
- }
+
+ return 0.0f;
}
void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings)
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp
index 0967984899d..0555ee24b9b 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.cpp
+++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp
@@ -34,7 +34,7 @@ InpaintSimpleOperation::InpaintSimpleOperation() : NodeOperation()
this->setComplex(true);
this->m_inputImageProgram = NULL;
this->m_pixelorder = NULL;
- this->m_manhatten_distance = NULL;
+ this->m_manhattan_distance = NULL;
this->m_cached_buffer = NULL;
this->m_cached_buffer_ready = false;
}
@@ -43,7 +43,7 @@ void InpaintSimpleOperation::initExecution()
this->m_inputImageProgram = this->getInputSocketReader(0);
this->m_pixelorder = NULL;
- this->m_manhatten_distance = NULL;
+ this->m_manhattan_distance = NULL;
this->m_cached_buffer = NULL;
this->m_cached_buffer_ready = false;
@@ -85,7 +85,7 @@ int InpaintSimpleOperation::mdist(int x, int y)
ASSERT_XY_RANGE(x, y);
- return this->m_manhatten_distance[y * width + x];
+ return this->m_manhattan_distance[y * width + x];
}
bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters)
@@ -108,11 +108,11 @@ bool InpaintSimpleOperation::next_pixel(int &x, int &y, int &curr, int iters)
return true;
}
-void InpaintSimpleOperation::calc_manhatten_distance()
+void InpaintSimpleOperation::calc_manhattan_distance()
{
int width = this->getWidth();
int height = this->getHeight();
- short *m = this->m_manhatten_distance = (short *)MEM_mallocN(sizeof(short) * width * height,
+ short *m = this->m_manhattan_distance = (short *)MEM_mallocN(sizeof(short) * width * height,
__func__);
int *offsets;
@@ -223,7 +223,7 @@ void *InpaintSimpleOperation::initializeTileData(rcti *rect)
MemoryBuffer *buf = (MemoryBuffer *)this->m_inputImageProgram->initializeTileData(rect);
this->m_cached_buffer = (float *)MEM_dupallocN(buf->getBuffer());
- this->calc_manhatten_distance();
+ this->calc_manhattan_distance();
int curr = 0;
int x, y;
@@ -258,9 +258,9 @@ void InpaintSimpleOperation::deinitExecution()
this->m_pixelorder = NULL;
}
- if (this->m_manhatten_distance) {
- MEM_freeN(this->m_manhatten_distance);
- this->m_manhatten_distance = NULL;
+ if (this->m_manhattan_distance) {
+ MEM_freeN(this->m_manhattan_distance);
+ this->m_manhattan_distance = NULL;
}
this->m_cached_buffer_ready = false;
}
@@ -272,14 +272,13 @@ bool InpaintSimpleOperation::determineDependingAreaOfInterest(rcti * /*input*/,
if (this->m_cached_buffer_ready) {
return false;
}
- else {
- rcti newInput;
- newInput.xmax = getWidth();
- newInput.xmin = 0;
- newInput.ymax = getHeight();
- newInput.ymin = 0;
+ rcti newInput;
- return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
- }
+ newInput.xmax = getWidth();
+ newInput.xmin = 0;
+ newInput.ymax = getHeight();
+ newInput.ymin = 0;
+
+ return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
diff --git a/source/blender/compositor/operations/COM_InpaintOperation.h b/source/blender/compositor/operations/COM_InpaintOperation.h
index 12523d5f064..86f3393e1ea 100644
--- a/source/blender/compositor/operations/COM_InpaintOperation.h
+++ b/source/blender/compositor/operations/COM_InpaintOperation.h
@@ -34,7 +34,7 @@ class InpaintSimpleOperation : public NodeOperation {
int *m_pixelorder;
int m_area_size;
- short *m_manhatten_distance;
+ short *m_manhattan_distance;
public:
InpaintSimpleOperation();
@@ -65,7 +65,7 @@ class InpaintSimpleOperation : public NodeOperation {
rcti *output);
private:
- void calc_manhatten_distance();
+ void calc_manhattan_distance();
void clamp_xy(int &x, int &y);
float *get_pixel(int x, int y);
int mdist(int x, int y);
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
index de55c9fb4b8..9101b82202a 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -87,14 +87,13 @@ bool MapUVOperation::read_uv(float x, float y, float &r_u, float &r_v, float &r_
r_alpha = 0.0f;
return false;
}
- else {
- float vector[3];
- m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
- r_u = vector[0] * m_inputColorProgram->getWidth();
- r_v = vector[1] * m_inputColorProgram->getHeight();
- r_alpha = vector[2];
- return true;
- }
+
+ float vector[3];
+ m_inputUVProgram->readSampled(vector, x, y, COM_PS_BILINEAR);
+ r_u = vector[0] * m_inputColorProgram->getWidth();
+ r_v = vector[1] * m_inputColorProgram->getHeight();
+ r_alpha = vector[2];
+ return true;
}
void MapUVOperation::pixelTransform(const float xy[2],
diff --git a/source/blender/compositor/operations/COM_OutputFileOperation.cpp b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
index ee3779edcb4..374189a5c50 100644
--- a/source/blender/compositor/operations/COM_OutputFileOperation.cpp
+++ b/source/blender/compositor/operations/COM_OutputFileOperation.cpp
@@ -129,9 +129,8 @@ static float *init_buffer(unsigned int width, unsigned int height, DataType data
int size = get_datatype_size(datatype);
return (float *)MEM_callocN(width * height * size * sizeof(float), "OutputFile buffer");
}
- else {
- return NULL;
- }
+
+ return NULL;
}
static void write_buffer_rect(rcti *rect,
diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
index 738c51fc719..b7731a34c91 100644
--- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
+++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
@@ -124,9 +124,8 @@ bool ScreenLensDistortionOperation::get_delta(float r_sq,
distort_uv(uv, t, delta);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
void ScreenLensDistortionOperation::accumulate(MemoryBuffer *buffer,
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
index 6f47e0e190b..4a7139537c1 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
@@ -172,7 +172,7 @@ template<int fxu, int fxv, int fyu, int fyv> struct BufferLineAccumulator {
return;
}
- /* initialise the iteration variables */
+ /* Initialize the iteration variables. */
float *buffer = init_buffer_iterator(
input, source, co, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
zero_v3(border);
diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
index 56e0ab9b93f..0f81780bb00 100644
--- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp
@@ -115,9 +115,8 @@ bool VectorBlurOperation::determineDependingAreaOfInterest(rcti * /*input*/,
newInput.ymin = 0;
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
- else {
- return false;
- }
+
+ return false;
}
void VectorBlurOperation::generateVectorBlur(float *data,
diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp
index fc26d6219e1..3d5d50e1c7f 100644
--- a/source/blender/compositor/operations/COM_ViewerOperation.cpp
+++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp
@@ -199,7 +199,6 @@ CompositorPriority ViewerOperation::getRenderPriority() const
if (this->isActiveViewerOutput()) {
return COM_PRIORITY_HIGH;
}
- else {
- return COM_PRIORITY_LOW;
- }
+
+ return COM_PRIORITY_LOW;
}
diff --git a/source/blender/datatoc/datatoc_icon.c b/source/blender/datatoc/datatoc_icon.c
index 80a335e22b7..4a9c5875c17 100644
--- a/source/blender/datatoc/datatoc_icon.c
+++ b/source/blender/datatoc/datatoc_icon.c
@@ -269,7 +269,7 @@ static bool icon_merge(const char *file_src,
/* init once */
*r_canvas_w = head.canvas_w;
*r_canvas_h = head.canvas_h;
- *r_pixels_canvas = calloc(1, (head.canvas_w * head.canvas_h) * sizeof(unsigned char[4]));
+ *r_pixels_canvas = calloc(1, (head.canvas_w * head.canvas_h) * sizeof(const unsigned char[4]));
}
canvas_w = *r_canvas_w;
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 51fce738700..417aaa2c4c0 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -54,6 +54,11 @@ set(SRC
intern/builder/deg_builder_remove_noop.cc
intern/builder/deg_builder_rna.cc
intern/builder/deg_builder_transitive.cc
+ intern/builder/pipeline.cc
+ intern/builder/pipeline_compositor.cc
+ intern/builder/pipeline_from_ids.cc
+ intern/builder/pipeline_render.cc
+ intern/builder/pipeline_view_layer.cc
intern/debug/deg_debug.cc
intern/debug/deg_debug_relations_graphviz.cc
intern/debug/deg_debug_stats_gnuplot.cc
@@ -110,6 +115,11 @@ set(SRC
intern/builder/deg_builder_remove_noop.h
intern/builder/deg_builder_rna.h
intern/builder/deg_builder_transitive.h
+ intern/builder/pipeline.h
+ intern/builder/pipeline_compositor.h
+ intern/builder/pipeline_from_ids.h
+ intern/builder/pipeline_render.h
+ intern/builder/pipeline_view_layer.h
intern/debug/deg_debug.h
intern/debug/deg_time_average.h
intern/eval/deg_eval.h
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index dcdcf0c05ca..e262c880421 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1126,6 +1126,12 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
if (object->type != OB_MESH) {
continue;
}
+ if (object->rigidbody_object == nullptr) {
+ continue;
+ }
+ if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+ continue;
+ }
/* Create operation for flushing results. */
/* Object's transform component - where the rigidbody operation
* lives. */
@@ -1466,6 +1472,18 @@ void DepsgraphNodeBuilder::build_light(Light *lamp)
function_bind(BKE_light_eval, _1, lamp_cow));
}
+void DepsgraphNodeBuilder::build_nodetree_socket(bNodeSocket *socket)
+{
+ build_idproperties(socket->prop);
+
+ if (socket->type == SOCK_OBJECT) {
+ build_id((ID *)((bNodeSocketValueObject *)socket->default_value)->value);
+ }
+ else if (socket->type == SOCK_IMAGE) {
+ build_id((ID *)((bNodeSocketValueImage *)socket->default_value)->value);
+ }
+}
+
void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
{
if (ntree == nullptr) {
@@ -1494,10 +1512,10 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
ID *id = bnode->id;
@@ -1780,8 +1798,10 @@ void DepsgraphNodeBuilder::build_simulation(Simulation *simulation)
return;
}
add_id_node(&simulation->id);
+ build_idproperties(simulation->id.properties);
build_animdata(&simulation->id);
build_parameters(&simulation->id);
+ build_nodetree(simulation->nodetree);
Simulation *simulation_cow = get_cow_datablock(simulation);
Scene *scene_cow = get_cow_datablock(scene_);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 256fa3450a6..40f42705a52 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -31,6 +31,7 @@
#include "DEG_depsgraph.h"
+struct bNodeSocket;
struct CacheFile;
struct Camera;
struct Collection;
@@ -211,6 +212,7 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder {
virtual void build_camera(Camera *camera);
virtual void build_light(Light *lamp);
virtual void build_nodetree(bNodeTree *ntree);
+ virtual void build_nodetree_socket(bNodeSocket *socket);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
virtual void build_freestyle_lineset(FreestyleLineSet *fls);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index c5c509ee853..6d76829fa1d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -254,9 +254,8 @@ TimeSourceNode *DepsgraphRelationBuilder::get_node(const TimeSourceKey &key) con
/* XXX TODO */
return nullptr;
}
- else {
- return graph_->time_source;
- }
+
+ return graph_->time_source;
}
ComponentNode *DepsgraphRelationBuilder::get_node(const ComponentKey &key) const
@@ -353,16 +352,16 @@ Relation *DepsgraphRelationBuilder::add_time_relation(TimeSourceNode *timesrc,
if (timesrc && node_to) {
return graph_->add_new_relation(timesrc, node_to, description, flags);
}
- else {
- DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
- BUILD,
- "add_time_relation(%p = %s, %p = %s, %s) Failed\n",
- timesrc,
- (timesrc) ? timesrc->identifier().c_str() : "<None>",
- node_to,
- (node_to) ? node_to->identifier().c_str() : "<None>",
- description);
- }
+
+ DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
+ BUILD,
+ "add_time_relation(%p = %s, %p = %s, %s) Failed\n",
+ timesrc,
+ (timesrc) ? timesrc->identifier().c_str() : "<None>",
+ node_to,
+ (node_to) ? node_to->identifier().c_str() : "<None>",
+ description);
+
return nullptr;
}
@@ -374,16 +373,16 @@ Relation *DepsgraphRelationBuilder::add_operation_relation(OperationNode *node_f
if (node_from && node_to) {
return graph_->add_new_relation(node_from, node_to, description, flags);
}
- else {
- DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
- BUILD,
- "add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
- node_from,
- (node_from) ? node_from->identifier().c_str() : "<None>",
- node_to,
- (node_to) ? node_to->identifier().c_str() : "<None>",
- description);
- }
+
+ DEG_DEBUG_PRINTF((::Depsgraph *)graph_,
+ BUILD,
+ "add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
+ node_from,
+ (node_from) ? node_from->identifier().c_str() : "<None>",
+ node_to,
+ (node_to) ? node_to->identifier().c_str() : "<None>",
+ description);
+
return nullptr;
}
@@ -1698,6 +1697,22 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
if (object->type != OB_MESH) {
continue;
}
+ if (object->rigidbody_object == nullptr) {
+ continue;
+ }
+ if (object->rigidbody_object->type == RBO_TYPE_PASSIVE) {
+ continue;
+ }
+
+ if (object->parent != nullptr && object->parent->rigidbody_object != nullptr &&
+ object->parent->rigidbody_object->shape == RB_SHAPE_COMPOUND) {
+ /* If we are a child of a compound shape object, the transforms and sim evaluation will be
+ * handled by the parent compound shape object. Do not add any evaluation triggers
+ * for the child objects.
+ */
+ continue;
+ }
+
OperationKey rb_transform_copy_key(
&object->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
/* Rigid body synchronization depends on the actual simulation. */
@@ -1747,13 +1762,18 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* final result of the constraint object's transform controls how
* the constraint affects the physics sim for these objects. */
ComponentKey trans_key(&object->id, NodeType::TRANSFORM);
- OperationKey ob1_key(
- &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- OperationKey ob2_key(
- &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
- /* Constrained-objects sync depends on the constraint-holder. */
- add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
- add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
+ if (rbc->ob1->rigidbody_object->type == RBO_TYPE_ACTIVE) {
+ OperationKey ob1_key(
+ &rbc->ob1->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
+ /* Constrained-objects sync depends on the constraint-holder. */
+ add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
+ }
+ if (rbc->ob2->rigidbody_object->type == RBO_TYPE_ACTIVE) {
+ OperationKey ob2_key(
+ &rbc->ob2->id, NodeType::TRANSFORM, OperationCode::RIGIDBODY_TRANSFORM_COPY);
+ /* Constrained-objects sync depends on the constraint-holder. */
+ add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
+ }
/* Ensure that sim depends on this constraint's transform. */
add_relation(trans_key, rb_simulate_key, "RigidBodyConstraint Transform -> RB Simulation");
}
@@ -2276,6 +2296,24 @@ void DepsgraphRelationBuilder::build_light(Light *lamp)
add_relation(lamp_parameters_key, shading_key, "Light Shading Parameters");
}
+void DepsgraphRelationBuilder::build_nodetree_socket(bNodeSocket *socket)
+{
+ build_idproperties(socket->prop);
+
+ if (socket->type == SOCK_OBJECT) {
+ Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
+ if (object != nullptr) {
+ build_object(object);
+ }
+ }
+ else if (socket->type == SOCK_IMAGE) {
+ Image *image = ((bNodeSocketValueImage *)socket->default_value)->value;
+ if (image != nullptr) {
+ build_image(image);
+ }
+ }
+}
+
void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
{
if (ntree == nullptr) {
@@ -2292,10 +2330,10 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
LISTBASE_FOREACH (bNode *, bnode, &ntree->nodes) {
build_idproperties(bnode->prop);
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->inputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &bnode->outputs) {
- build_idproperties(socket->prop);
+ build_nodetree_socket(socket);
}
ID *id = bnode->id;
@@ -2602,13 +2640,39 @@ void DepsgraphRelationBuilder::build_simulation(Simulation *simulation)
if (built_map_.checkIsBuiltAndTag(simulation)) {
return;
}
+ build_idproperties(simulation->id.properties);
build_animdata(&simulation->id);
build_parameters(&simulation->id);
- OperationKey simulation_update_key(
+ build_nodetree(simulation->nodetree);
+ build_nested_nodetree(&simulation->id, simulation->nodetree);
+
+ OperationKey simulation_eval_key(
&simulation->id, NodeType::SIMULATION, OperationCode::SIMULATION_EVAL);
TimeSourceKey time_src_key;
- add_relation(time_src_key, simulation_update_key, "TimeSrc -> Simulation");
+ add_relation(time_src_key, simulation_eval_key, "TimeSrc -> Simulation");
+
+ OperationKey nodetree_key(
+ &simulation->nodetree->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EXIT);
+ add_relation(nodetree_key, simulation_eval_key, "NodeTree -> Simulation", 0);
+
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation->dependencies) {
+ if (dependency->id == nullptr) {
+ continue;
+ }
+ build_id(dependency->id);
+ if (GS(dependency->id->name) == ID_OB) {
+ Object *object = (Object *)dependency->id;
+ if (dependency->flag & SIM_DEPENDS_ON_TRANSFORM) {
+ ComponentKey object_transform_key(&object->id, NodeType::TRANSFORM);
+ add_relation(object_transform_key, simulation_eval_key, "Object Transform -> Simulation");
+ }
+ if (dependency->flag & SIM_DEPENDS_ON_GEOMETRY) {
+ ComponentKey object_geometry_key(&object->id, NodeType::GEOMETRY);
+ add_relation(object_geometry_key, simulation_eval_key, "Object Geometry -> Simulation");
+ }
+ }
+ }
}
void DepsgraphRelationBuilder::build_scene_sequencer(Scene *scene)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index b4b0dc71f85..04f2a3f911d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -46,6 +46,7 @@
#include "intern/node/deg_node_operation.h"
struct Base;
+struct bNodeSocket;
struct CacheFile;
struct Camera;
struct Collection;
@@ -275,6 +276,7 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder {
virtual void build_camera(Camera *camera);
virtual void build_light(Light *lamp);
virtual void build_nodetree(bNodeTree *ntree);
+ virtual void build_nodetree_socket(bNodeSocket *socket);
virtual void build_material(Material *ma);
virtual void build_materials(Material **materials, int num_materials);
virtual void build_freestyle_lineset(FreestyleLineSet *fls);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
index e3b667427a2..ec18b429c2e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc
@@ -190,7 +190,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
reinterpret_cast<const PropertyRNA *>(prop));
return node_identifier;
}
- else if (ptr->type == &RNA_PoseBone) {
+ if (ptr->type == &RNA_PoseBone) {
const bPoseChannel *pchan = static_cast<const bPoseChannel *>(ptr->data);
/* Bone - generally, we just want the bone component. */
node_identifier.type = NodeType::BONE;
@@ -222,7 +222,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
}
return node_identifier;
}
- else if (ptr->type == &RNA_Bone) {
+ if (ptr->type == &RNA_Bone) {
/* Armature-level bone mapped to Armature Eval, and thus Pose Init.
* Drivers have special code elsewhere that links them to the pose
* bone components, instead of using this generic code. */
@@ -236,7 +236,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
}
return node_identifier;
}
- else if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
+ if (RNA_struct_is_a(ptr->type, &RNA_Constraint)) {
const Object *object = reinterpret_cast<const Object *>(ptr->owner_id);
const bConstraint *constraint = static_cast<const bConstraint *>(ptr->data);
RNANodeQueryIDData *id_data = ensure_id_data(&object->id);
@@ -256,7 +256,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
}
return node_identifier;
}
- else if (ELEM(ptr->type, &RNA_ConstraintTarget, &RNA_ConstraintTargetBone)) {
+ if (ELEM(ptr->type, &RNA_ConstraintTarget, &RNA_ConstraintTargetBone)) {
Object *object = reinterpret_cast<Object *>(ptr->owner_id);
bConstraintTarget *tgt = (bConstraintTarget *)ptr->data;
/* Check whether is object or bone constraint. */
@@ -315,17 +315,17 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr,
node_identifier.type = NodeType::TRANSFORM;
return node_identifier;
}
- else if (contains(prop_identifier, "data")) {
+ if (contains(prop_identifier, "data")) {
/* We access object.data, most likely a geometry.
* Might be a bone tho. */
node_identifier.type = NodeType::GEOMETRY;
return node_identifier;
}
- else if (STREQ(prop_identifier, "hide_viewport") || STREQ(prop_identifier, "hide_render")) {
+ if (STREQ(prop_identifier, "hide_viewport") || STREQ(prop_identifier, "hide_render")) {
node_identifier.type = NodeType::OBJECT_FROM_LAYER;
return node_identifier;
}
- else if (STREQ(prop_identifier, "dimensions")) {
+ if (STREQ(prop_identifier, "dimensions")) {
node_identifier.type = NodeType::PARAMETERS;
node_identifier.operation_code = OperationCode::DIMENSIONS;
return node_identifier;
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.h b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
index c48c6489c47..d03903d508c 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_rna.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.h
@@ -96,7 +96,7 @@ class RNANodeQuery {
/* Check whether prop_identifier contains rna_path_component.
*
- * This checks more than a substring:
+ * This checks more than a sub-string:
*
* prop_identifier contains(prop_identifier, "location")
* ------------------------ -------------------------------------
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
index bd6a364e08a..c5e020b3242 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
@@ -96,7 +96,7 @@ void deg_graph_transitive_reduction(Depsgraph *graph)
* need modifying. */
continue;
}
- else if (rel->from->custom_flags & OP_REACHABLE) {
+ if (rel->from->custom_flags & OP_REACHABLE) {
relations_to_remove.append(rel);
}
}
diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc
new file mode 100644
index 00000000000..d6893ba11d8
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline.cc
@@ -0,0 +1,132 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline.h"
+
+#include "PIL_time.h"
+
+#include "BKE_global.h"
+
+#include "DNA_scene_types.h"
+
+#include "deg_builder_cycle.h"
+#include "deg_builder_nodes.h"
+#include "deg_builder_relations.h"
+#include "deg_builder_transitive.h"
+
+namespace blender {
+namespace deg {
+
+AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : deg_graph_(reinterpret_cast<Depsgraph *>(graph)),
+ bmain_(bmain),
+ scene_(scene),
+ view_layer_(view_layer),
+ builder_cache_()
+{
+}
+
+AbstractBuilderPipeline::~AbstractBuilderPipeline()
+{
+}
+
+void AbstractBuilderPipeline::build()
+{
+ double start_time = 0.0;
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ start_time = PIL_check_seconds_timer();
+ }
+
+ build_step_sanity_check();
+ build_step_nodes();
+ build_step_relations();
+ build_step_finalize();
+
+ if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
+ printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
+ }
+}
+
+void AbstractBuilderPipeline::build_step_sanity_check()
+{
+ BLI_assert(BLI_findindex(&scene_->view_layers, view_layer_) != -1);
+ BLI_assert(deg_graph_->scene == scene_);
+ BLI_assert(deg_graph_->view_layer == view_layer_);
+}
+
+void AbstractBuilderPipeline::build_step_nodes()
+{
+ /* Generate all the nodes in the graph first */
+ unique_ptr<DepsgraphNodeBuilder> node_builder = construct_node_builder();
+ node_builder->begin_build();
+ build_nodes(*node_builder);
+ node_builder->end_build();
+}
+
+void AbstractBuilderPipeline::build_step_relations()
+{
+ /* Hook up relationships between operations - to determine evaluation order. */
+ unique_ptr<DepsgraphRelationBuilder> relation_builder = construct_relation_builder();
+ relation_builder->begin_build();
+ build_relations(*relation_builder);
+ relation_builder->build_copy_on_write_relations();
+ relation_builder->build_driver_relations();
+}
+
+void AbstractBuilderPipeline::build_step_finalize()
+{
+ /* Detect and solve cycles. */
+ deg_graph_detect_cycles(deg_graph_);
+ /* Simplify the graph by removing redundant relations (to optimize
+ * traversal later). */
+ /* TODO: it would be useful to have an option to disable this in cases where
+ * it is causing trouble. */
+ if (G.debug_value == 799) {
+ deg_graph_transitive_reduction(deg_graph_);
+ }
+ /* Store pointers to commonly used valuated datablocks. */
+ deg_graph_->scene_cow = (Scene *)deg_graph_->get_cow_id(&deg_graph_->scene->id);
+ /* Flush visibility layer and re-schedule nodes for update. */
+ deg_graph_build_finalize(bmain_, deg_graph_);
+ DEG_graph_on_visible_update(bmain_, reinterpret_cast<::Depsgraph *>(deg_graph_), false);
+#if 0
+ if (!DEG_debug_consistency_check(deg_graph_)) {
+ printf("Consistency validation failed, ABORTING!\n");
+ abort();
+ }
+#endif
+ /* Relations are up to date. */
+ deg_graph_->need_update = false;
+}
+
+unique_ptr<DepsgraphNodeBuilder> AbstractBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<DepsgraphNodeBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> AbstractBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<DepsgraphRelationBuilder>(bmain_, deg_graph_, &builder_cache_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline.h b/source/blender/depsgraph/intern/builder/pipeline.h
new file mode 100644
index 00000000000..2c9c78bb2cb
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline.h
@@ -0,0 +1,77 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "deg_builder_cache.h"
+
+#include "intern/depsgraph_type.h"
+
+struct Main;
+struct Scene;
+struct ViewLayer;
+struct Depsgraph;
+
+namespace blender {
+namespace deg {
+
+struct Depsgraph;
+class DepsgraphNodeBuilder;
+class DepsgraphRelationBuilder;
+
+/* Base class for Depsgraph Builder pipelines.
+ *
+ * Basically it runs through the following steps:
+ * - sanity check
+ * - build nodes
+ * - build relations
+ * - finalize
+ */
+class AbstractBuilderPipeline {
+ public:
+ AbstractBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+ virtual ~AbstractBuilderPipeline();
+
+ void build();
+
+ protected:
+ Depsgraph *deg_graph_;
+ Main *bmain_;
+ Scene *scene_;
+ ViewLayer *view_layer_;
+ DepsgraphBuilderCache builder_cache_;
+
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder();
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder();
+
+ virtual void build_step_sanity_check();
+ void build_step_nodes();
+ void build_step_relations();
+ void build_step_finalize();
+
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) = 0;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) = 0;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.cc b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
new file mode 100644
index 00000000000..3e56f17fc7e
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.cc
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_compositor.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+CompositorBuilderPipeline::CompositorBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer), nodetree_(nodetree)
+{
+ deg_graph_->is_render_pipeline_depsgraph = true;
+}
+
+void CompositorBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_scene_render(scene_, view_layer_);
+ node_builder.build_nodetree(nodetree_);
+}
+
+void CompositorBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_scene_render(scene_, view_layer_);
+ relation_builder.build_nodetree(nodetree_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_compositor.h b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
new file mode 100644
index 00000000000..892ece7c2a4
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_compositor.h
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+struct bNodeTree;
+
+namespace blender {
+namespace deg {
+
+class CompositorBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ CompositorBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, bNodeTree *nodetree);
+
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+
+ private:
+ bNodeTree *nodetree_;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
new file mode 100644
index 00000000000..e44f554f197
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.cc
@@ -0,0 +1,154 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_from_ids.h"
+
+#include "DNA_layer_types.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+namespace {
+
+class DepsgraphFromIDsFilter {
+ public:
+ DepsgraphFromIDsFilter(ID **ids, const int num_ids)
+ {
+ for (int i = 0; i < num_ids; ++i) {
+ ids_.add(ids[i]);
+ }
+ }
+
+ bool contains(ID *id)
+ {
+ return ids_.contains(id);
+ }
+
+ protected:
+ Set<ID *> ids_;
+};
+
+class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
+ public:
+ DepsgraphFromIDsNodeBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object, bool is_visible) override
+ {
+ if (object->proxy_group == nullptr) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
+ public:
+ DepsgraphFromIDsRelationBuilder(
+ Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
+ : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
+ {
+ }
+
+ virtual bool need_pull_base_into_graph(Base *base) override
+ {
+ if (!filter_.contains(&base->object->id)) {
+ return false;
+ }
+ return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
+ }
+
+ virtual void build_object_proxy_group(Object *object) override
+ {
+ if (object->proxy_group == nullptr) {
+ return;
+ }
+ if (!filter_.contains(&object->proxy_group->id)) {
+ return;
+ }
+ DepsgraphRelationBuilder::build_object_proxy_group(object);
+ }
+
+ protected:
+ DepsgraphFromIDsFilter filter_;
+};
+
+} // namespace
+
+FromIDsBuilderPipeline::FromIDsBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer,
+ ID **ids,
+ const int num_ids)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer), ids_(ids), num_ids_(num_ids)
+{
+}
+
+unique_ptr<DepsgraphNodeBuilder> FromIDsBuilderPipeline::construct_node_builder()
+{
+ return std::make_unique<DepsgraphFromIDsNodeBuilder>(
+ bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+}
+
+unique_ptr<DepsgraphRelationBuilder> FromIDsBuilderPipeline::construct_relation_builder()
+{
+ return std::make_unique<DepsgraphFromIDsRelationBuilder>(
+ bmain_, deg_graph_, &builder_cache_, ids_, num_ids_);
+}
+
+void FromIDsBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids_; ++i) {
+ node_builder.build_id(ids_[i]);
+ }
+}
+
+void FromIDsBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+ for (int i = 0; i < num_ids_; ++i) {
+ relation_builder.build_id(ids_[i]);
+ }
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_from_ids.h b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
new file mode 100644
index 00000000000..4a507f2c728
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_from_ids.h
@@ -0,0 +1,62 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+/* Optimized builders for dependency graph built from a given set of IDs.
+ *
+ * General notes:
+ *
+ * - We pull in all bases if their objects are in the set of IDs. This allows to have proper
+ * visibility and other flags assigned to the objects.
+ * All other bases (the ones which points to object which is outside of the set of IDs) are
+ * completely ignored.
+ *
+ * - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
+ * This way we avoid high-poly character body pulled into the dependency graph when it's coming
+ * from a library into an animation file and the dependency graph constructed for a proxy rig. */
+
+class FromIDsBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ FromIDsBuilderPipeline(
+ ::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer, ID **ids, int num_ids);
+
+ protected:
+ virtual unique_ptr<DepsgraphNodeBuilder> construct_node_builder() override;
+ virtual unique_ptr<DepsgraphRelationBuilder> construct_relation_builder() override;
+
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+
+ private:
+ ID **ids_;
+ const int num_ids_;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.cc b/source/blender/depsgraph/intern/builder/pipeline_render.cc
new file mode 100644
index 00000000000..50a37d0d3e4
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.cc
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_render.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+RenderBuilderPipeline::RenderBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+{
+ deg_graph_->is_render_pipeline_depsgraph = true;
+}
+
+void RenderBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_scene_render(scene_, view_layer_);
+}
+
+void RenderBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_scene_render(scene_, view_layer_);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_render.h b/source/blender/depsgraph/intern/builder/pipeline_render.h
new file mode 100644
index 00000000000..df7f9e0de68
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_render.h
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+class RenderBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ RenderBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
new file mode 100644
index 00000000000..3223f17f349
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.cc
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "pipeline_view_layer.h"
+
+#include "intern/builder/deg_builder_nodes.h"
+#include "intern/builder/deg_builder_relations.h"
+#include "intern/depsgraph.h"
+
+namespace blender {
+namespace deg {
+
+ViewLayerBuilderPipeline::ViewLayerBuilderPipeline(::Depsgraph *graph,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *view_layer)
+ : AbstractBuilderPipeline(graph, bmain, scene, view_layer)
+{
+}
+
+void ViewLayerBuilderPipeline::build_nodes(DepsgraphNodeBuilder &node_builder)
+{
+ node_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+}
+
+void ViewLayerBuilderPipeline::build_relations(DepsgraphRelationBuilder &relation_builder)
+{
+ relation_builder.build_view_layer(scene_, view_layer_, DEG_ID_LINKED_DIRECTLY);
+}
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/builder/pipeline_view_layer.h b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
new file mode 100644
index 00000000000..fbd7b98acad
--- /dev/null
+++ b/source/blender/depsgraph/intern/builder/pipeline_view_layer.h
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup depsgraph
+ */
+
+#pragma once
+
+#include "pipeline.h"
+
+namespace blender {
+namespace deg {
+
+class ViewLayerBuilderPipeline : public AbstractBuilderPipeline {
+ public:
+ ViewLayerBuilderPipeline(::Depsgraph *graph, Main *bmain, Scene *scene, ViewLayer *view_layer);
+
+ protected:
+ virtual void build_nodes(DepsgraphNodeBuilder &node_builder) override;
+ virtual void build_relations(DepsgraphRelationBuilder &relation_builder) override;
+};
+
+} // namespace deg
+} // namespace blender
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
index 458baf4fb1e..d0356f44022 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_relations_graphviz.cc
@@ -25,6 +25,7 @@
#include <cstdarg>
+#include "BLI_dot_export.hh"
#include "BLI_utildefines.h"
#include "DNA_listBase.h"
@@ -41,6 +42,7 @@
#include "intern/node/deg_node_time.h"
namespace deg = blender::deg;
+namespace dot = blender::dot;
/* ****************** */
/* Graphviz Debugging */
@@ -48,8 +50,6 @@ namespace deg = blender::deg;
namespace blender {
namespace deg {
-#define NL "\r\n"
-
/* Only one should be enabled, defines whether graphviz nodes
* get colored by individual types or classes.
*/
@@ -158,47 +158,43 @@ static int deg_debug_node_color_index(const Node *node)
#endif
}
-struct DebugContext {
- FILE *file;
+struct DotExportContext {
bool show_tags;
+ dot::DirectedGraph &digraph;
+ Map<const Node *, dot::Node *> nodes_map;
+ Map<const Node *, dot::Cluster *> clusters_map;
};
-static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
- ATTR_PRINTF_FORMAT(2, 3);
-static void deg_debug_fprintf(const DebugContext &ctx, const char *fmt, ...)
+static void deg_debug_graphviz_legend_color(const char *name,
+ const char *color,
+ std::stringstream &ss)
{
- va_list args;
- va_start(args, fmt);
- vfprintf(ctx.file, fmt, args);
- va_end(args);
-}
-static void deg_debug_graphviz_legend_color(const DebugContext &ctx,
- const char *name,
- const char *color)
-{
- deg_debug_fprintf(ctx, "<TR>");
- deg_debug_fprintf(ctx, "<TD>%s</TD>", name);
- deg_debug_fprintf(ctx, "<TD BGCOLOR=\"%s\"></TD>", color);
- deg_debug_fprintf(ctx, "</TR>" NL);
+ ss << "<TR>";
+ ss << "<TD>" << name << "</TD>";
+ ss << "<TD BGCOLOR=\"" << color << "\"></TD>";
+ ss << "</TR>";
}
-static void deg_debug_graphviz_legend(const DebugContext &ctx)
+static void deg_debug_graphviz_legend(DotExportContext &ctx)
{
- deg_debug_fprintf(ctx, "{" NL);
- deg_debug_fprintf(ctx, "rank = sink;" NL);
- deg_debug_fprintf(ctx, "Legend [shape=none, margin=0, label=<" NL);
- deg_debug_fprintf(
- ctx, " <TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">" NL);
- deg_debug_fprintf(ctx, "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>" NL);
+ dot::Node &legend_node = ctx.digraph.new_node("");
+ legend_node.attributes.set("rank", "sink");
+ legend_node.attributes.set("shape", "none");
+ legend_node.attributes.set("margin", 0);
+
+ std::stringstream ss;
+ ss << "<";
+ ss << "<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">";
+ ss << "<TR><TD COLSPAN=\"2\"><B>Legend</B></TD></TR>";
#ifdef COLOR_SCHEME_NODE_CLASS
const char **colors = deg_debug_colors_light;
- deg_debug_graphviz_legend_color(ctx, "Operation", colors[4]);
- deg_debug_graphviz_legend_color(ctx, "Component", colors[1]);
- deg_debug_graphviz_legend_color(ctx, "ID Node", colors[5]);
- deg_debug_graphviz_legend_color(ctx, "NOOP", colors[8]);
- deg_debug_graphviz_legend_color(ctx, "Pinned OP", colors[7]);
+ deg_debug_graphviz_legend_color("Operation", colors[4], ss);
+ deg_debug_graphviz_legend_color("Component", colors[1], ss);
+ deg_debug_graphviz_legend_color("ID Node", colors[5], ss);
+ deg_debug_graphviz_legend_color("NOOP", colors[8], ss);
+ deg_debug_graphviz_legend_color("Pinned OP", colors[7], ss);
#endif
#ifdef COLOR_SCHEME_NODE_TYPE
@@ -206,18 +202,19 @@ static void deg_debug_graphviz_legend(const DebugContext &ctx)
for (pair = deg_debug_node_type_color_map; (*pair)[0] >= 0; pair++) {
DepsNodeFactory *nti = type_get_factory((NodeType)(*pair)[0]);
deg_debug_graphviz_legend_color(
- ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors]);
+ ctx, nti->tname().c_str(), deg_debug_colors_light[(*pair)[1] % deg_debug_max_colors], ss);
}
#endif
- deg_debug_fprintf(ctx, "</TABLE>" NL);
- deg_debug_fprintf(ctx, ">" NL);
- deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, "}" NL);
+ ss << "</TABLE>";
+ ss << ">";
+ legend_node.attributes.set("label", ss.str());
+ legend_node.attributes.set("fontname", deg_debug_graphviz_fontname);
}
-static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_color(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
const char *color_default = "black";
const char *color_modified = "orangered4";
@@ -234,10 +231,12 @@ static void deg_debug_graphviz_node_color(const DebugContext &ctx, const Node *n
}
}
}
- deg_debug_fprintf(ctx, "\"%s\"", color);
+ dot_attributes.set("color", color);
}
-static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_penwidth(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
float penwidth_default = 1.0f;
float penwidth_modified = 4.0f;
@@ -254,20 +253,20 @@ static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx, const Node
}
}
}
- deg_debug_fprintf(ctx, "\"%f\"", penwidth);
+ dot_attributes.set("penwidth", penwidth);
}
-static void deg_debug_graphviz_node_fillcolor(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_fillcolor(const Node *node, dot::Attributes &dot_attributes)
{
const char *defaultcolor = "gainsboro";
int color_index = deg_debug_node_color_index(node);
const char *fillcolor = color_index < 0 ?
defaultcolor :
deg_debug_colors_light[color_index % deg_debug_max_colors];
- deg_debug_fprintf(ctx, "\"%s\"", fillcolor);
+ dot_attributes.set("fillcolor", fillcolor);
}
-static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_color(const Relation *rel, dot::DirectedEdge &edge)
{
const char *color_default = "black";
const char *color_cyclic = "red4"; /* The color of crime scene. */
@@ -279,10 +278,10 @@ static void deg_debug_graphviz_relation_color(const DebugContext &ctx, const Rel
else if (rel->flag & RELATION_FLAG_GODMODE) {
color = color_godmode;
}
- deg_debug_fprintf(ctx, "%s", color);
+ edge.attributes.set("color", color);
}
-static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_style(const Relation *rel, dot::DirectedEdge &edge)
{
const char *style_default = "solid";
const char *style_no_flush = "dashed";
@@ -294,10 +293,10 @@ static void deg_debug_graphviz_relation_style(const DebugContext &ctx, const Rel
if (rel->flag & RELATION_FLAG_FLUSH_USER_EDIT_ONLY) {
style = style_flush_user_only;
}
- deg_debug_fprintf(ctx, "%s", style);
+ edge.attributes.set("style", style);
}
-static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const Relation *rel)
+static void deg_debug_graphviz_relation_arrowhead(const Relation *rel, dot::DirectedEdge &edge)
{
const char *shape_default = "normal";
const char *shape_no_cow = "box";
@@ -311,12 +310,14 @@ static void deg_debug_graphviz_relation_arrowhead(const DebugContext &ctx, const
shape = shape_no_cow;
}
}
- deg_debug_fprintf(ctx, "%s", shape);
+ edge.attributes.set("arrowhead", shape);
}
-static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_style(DotExportContext &ctx,
+ const Node *node,
+ dot::Attributes &dot_attributes)
{
- const char *base_style = "filled"; /* default style */
+ StringRef base_style = "filled"; /* default style */
if (ctx.show_tags) {
if (node->get_class() == NodeClass::OPERATION) {
OperationNode *op_node = (OperationNode *)node;
@@ -327,95 +328,78 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const Node *n
}
switch (node->get_class()) {
case NodeClass::GENERIC:
- deg_debug_fprintf(ctx, "\"%s\"", base_style);
+ dot_attributes.set("style", base_style);
break;
case NodeClass::COMPONENT:
- deg_debug_fprintf(ctx, "\"%s\"", base_style);
+ dot_attributes.set("style", base_style);
break;
case NodeClass::OPERATION:
- deg_debug_fprintf(ctx, "\"%s,rounded\"", base_style);
+ dot_attributes.set("style", base_style + ",rounded");
break;
}
}
-static void deg_debug_graphviz_node_single(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_single(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
- const char *shape = "box";
string name = node->identifier();
- deg_debug_fprintf(ctx, "// %s\n", name.c_str());
- deg_debug_fprintf(ctx, "\"node_%p\"", node);
- deg_debug_fprintf(ctx, "[");
- // deg_debug_fprintf(ctx, "label=<<B>%s</B>>", name);
- deg_debug_fprintf(ctx, "label=<%s>", name.c_str());
- deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, ",fontsize=%f", deg_debug_graphviz_node_label_size);
- deg_debug_fprintf(ctx, ",shape=%s", shape);
- deg_debug_fprintf(ctx, ",style=");
- deg_debug_graphviz_node_style(ctx, node);
- deg_debug_fprintf(ctx, ",color=");
- deg_debug_graphviz_node_color(ctx, node);
- deg_debug_fprintf(ctx, ",fillcolor=");
- deg_debug_graphviz_node_fillcolor(ctx, node);
- deg_debug_fprintf(ctx, ",penwidth=");
- deg_debug_graphviz_node_penwidth(ctx, node);
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
+
+ dot::Node &dot_node = ctx.digraph.new_node(name);
+ ctx.nodes_map.add_new(node, &dot_node);
+ dot_node.set_parent_cluster(parent_cluster);
+ dot_node.attributes.set("fontname", deg_debug_graphviz_fontname);
+ dot_node.attributes.set("frontsize", deg_debug_graphviz_node_label_size);
+ dot_node.attributes.set("shape", "box");
+
+ deg_debug_graphviz_node_style(ctx, node, dot_node.attributes);
+ deg_debug_graphviz_node_color(ctx, node, dot_node.attributes);
+ deg_debug_graphviz_node_fillcolor(node, dot_node.attributes);
+ deg_debug_graphviz_node_penwidth(ctx, node, dot_node.attributes);
}
-static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx, const Node *node)
+static dot::Cluster &deg_debug_graphviz_node_cluster_create(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
string name = node->identifier();
- deg_debug_fprintf(ctx, "// %s\n", name.c_str());
- deg_debug_fprintf(ctx, "subgraph \"cluster_%p\" {" NL, node);
- // deg_debug_fprintf(ctx, "label=<<B>%s</B>>;" NL, name);
- deg_debug_fprintf(ctx, "label=<%s>;" NL, name.c_str());
- deg_debug_fprintf(ctx, "fontname=\"%s\";" NL, deg_debug_graphviz_fontname);
- deg_debug_fprintf(ctx, "fontsize=%f;" NL, deg_debug_graphviz_node_label_size);
- deg_debug_fprintf(ctx, "margin=\"%d\";" NL, 16);
- deg_debug_fprintf(ctx, "style=");
- deg_debug_graphviz_node_style(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "color=");
- deg_debug_graphviz_node_color(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "fillcolor=");
- deg_debug_graphviz_node_fillcolor(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
- deg_debug_fprintf(ctx, "penwidth=");
- deg_debug_graphviz_node_penwidth(ctx, node);
- deg_debug_fprintf(ctx, ";" NL);
+ dot::Cluster &cluster = ctx.digraph.new_cluster(name);
+ cluster.set_parent_cluster(parent_cluster);
+ cluster.attributes.set("fontname", deg_debug_graphviz_fontname);
+ cluster.attributes.set("fontsize", deg_debug_graphviz_node_label_size);
+ cluster.attributes.set("margin", 16);
+ deg_debug_graphviz_node_style(ctx, node, cluster.attributes);
+ deg_debug_graphviz_node_color(ctx, node, cluster.attributes);
+ deg_debug_graphviz_node_fillcolor(node, cluster.attributes);
+ deg_debug_graphviz_node_penwidth(ctx, node, cluster.attributes);
/* dummy node, so we can add edges between clusters */
- deg_debug_fprintf(ctx, "\"node_%p\"", node);
- deg_debug_fprintf(ctx, "[");
- deg_debug_fprintf(ctx, "shape=%s", "point");
- deg_debug_fprintf(ctx, ",style=%s", "invis");
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
+ dot::Node &dot_node = ctx.digraph.new_node("");
+ dot_node.attributes.set("shape", "point");
+ dot_node.attributes.set("style", "invis");
+ dot_node.set_parent_cluster(&cluster);
+ ctx.nodes_map.add_new(node, &dot_node);
+ ctx.clusters_map.add_new(node, &cluster);
+ return cluster;
}
-static void deg_debug_graphviz_node_cluster_end(const DebugContext &ctx)
-{
- deg_debug_fprintf(ctx, "}" NL);
- deg_debug_fprintf(ctx, NL);
-}
+static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph);
+static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph);
-static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph);
-static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph);
-
-static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node(DotExportContext &ctx,
+ const Node *node,
+ dot::Cluster *parent_cluster)
{
switch (node->type) {
case NodeType::ID_REF: {
const IDNode *id_node = (const IDNode *)node;
if (id_node->components.is_empty()) {
- deg_debug_graphviz_node_single(ctx, node);
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
}
else {
- deg_debug_graphviz_node_cluster_begin(ctx, node);
+ dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster);
for (const ComponentNode *comp : id_node->components.values()) {
- deg_debug_graphviz_node(ctx, comp);
+ deg_debug_graphviz_node(ctx, comp, &cluster);
}
- deg_debug_graphviz_node_cluster_end(ctx);
}
break;
}
@@ -445,127 +429,72 @@ static void deg_debug_graphviz_node(const DebugContext &ctx, const Node *node)
case NodeType::GENERIC_DATABLOCK:
case NodeType::SIMULATION: {
ComponentNode *comp_node = (ComponentNode *)node;
- if (!comp_node->operations.is_empty()) {
- deg_debug_graphviz_node_cluster_begin(ctx, node);
- for (Node *op_node : comp_node->operations) {
- deg_debug_graphviz_node(ctx, op_node);
- }
- deg_debug_graphviz_node_cluster_end(ctx);
+ if (comp_node->operations.is_empty()) {
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
}
else {
- deg_debug_graphviz_node_single(ctx, node);
+ dot::Cluster &cluster = deg_debug_graphviz_node_cluster_create(ctx, node, parent_cluster);
+ for (Node *op_node : comp_node->operations) {
+ deg_debug_graphviz_node(ctx, op_node, &cluster);
+ }
}
break;
}
case NodeType::UNDEFINED:
case NodeType::TIMESOURCE:
case NodeType::OPERATION:
- deg_debug_graphviz_node_single(ctx, node);
+ deg_debug_graphviz_node_single(ctx, node, parent_cluster);
break;
case NodeType::NUM_TYPES:
break;
}
}
-static bool deg_debug_graphviz_is_cluster(const Node *node)
-{
- switch (node->type) {
- case NodeType::ID_REF: {
- const IDNode *id_node = (const IDNode *)node;
- return !id_node->components.is_empty();
- }
- case NodeType::PARAMETERS:
- case NodeType::ANIMATION:
- case NodeType::TRANSFORM:
- case NodeType::PROXY:
- case NodeType::GEOMETRY:
- case NodeType::SEQUENCER:
- case NodeType::EVAL_POSE:
- case NodeType::BONE: {
- ComponentNode *comp_node = (ComponentNode *)node;
- return !comp_node->operations.is_empty();
- }
- default:
- return false;
- }
-}
-
-static bool deg_debug_graphviz_is_owner(const Node *node, const Node *other)
-{
- switch (node->get_class()) {
- case NodeClass::COMPONENT: {
- ComponentNode *comp_node = (ComponentNode *)node;
- if (comp_node->owner == other) {
- return true;
- }
- break;
- }
- case NodeClass::OPERATION: {
- OperationNode *op_node = (OperationNode *)node;
- if (op_node->owner == other) {
- return true;
- }
- else if (op_node->owner->owner == other) {
- return true;
- }
- break;
- }
- default:
- break;
- }
- return false;
-}
-
-static void deg_debug_graphviz_node_relations(const DebugContext &ctx, const Node *node)
+static void deg_debug_graphviz_node_relations(DotExportContext &ctx, const Node *node)
{
for (Relation *rel : node->inlinks) {
float penwidth = 2.0f;
- const Node *tail = rel->to; /* same as node */
- const Node *head = rel->from;
- deg_debug_fprintf(
- ctx, "// %s -> %s\n", head->identifier().c_str(), tail->identifier().c_str());
- deg_debug_fprintf(ctx, "\"node_%p\"", head);
- deg_debug_fprintf(ctx, " -> ");
- deg_debug_fprintf(ctx, "\"node_%p\"", tail);
+ const Node *head = rel->to; /* same as node */
+ const Node *tail = rel->from;
+ dot::Node &dot_tail = *ctx.nodes_map.lookup(tail);
+ dot::Node &dot_head = *ctx.nodes_map.lookup(head);
+
+ dot::DirectedEdge &edge = ctx.digraph.new_edge(dot_tail, dot_head);
- deg_debug_fprintf(ctx, "[");
/* Note: without label an id seem necessary to avoid bugs in graphviz/dot */
- deg_debug_fprintf(ctx, "id=\"%s\"", rel->name);
- // deg_debug_fprintf(ctx, "label=\"%s\"", rel->name);
- deg_debug_fprintf(ctx, ",color=");
- deg_debug_graphviz_relation_color(ctx, rel);
- deg_debug_fprintf(ctx, ",style=");
- deg_debug_graphviz_relation_style(ctx, rel);
- deg_debug_fprintf(ctx, ",arrowhead=");
- deg_debug_graphviz_relation_arrowhead(ctx, rel);
- deg_debug_fprintf(ctx, ",penwidth=\"%f\"", penwidth);
+ edge.attributes.set("id", rel->name);
+ deg_debug_graphviz_relation_color(rel, edge);
+ deg_debug_graphviz_relation_style(rel, edge);
+ deg_debug_graphviz_relation_arrowhead(rel, edge);
+ edge.attributes.set("penwidth", penwidth);
+
/* NOTE: edge from node to own cluster is not possible and gives graphviz
* warning, avoid this here by just linking directly to the invisible
* placeholder node. */
- if (deg_debug_graphviz_is_cluster(tail) && !deg_debug_graphviz_is_owner(head, tail)) {
- deg_debug_fprintf(ctx, ",ltail=\"cluster_%p\"", tail);
+ dot::Cluster *tail_cluster = ctx.clusters_map.lookup_default(tail, nullptr);
+ if (tail_cluster != nullptr && tail_cluster->contains(dot_head)) {
+ edge.attributes.set("ltail", tail_cluster->name());
}
- if (deg_debug_graphviz_is_cluster(head) && !deg_debug_graphviz_is_owner(tail, head)) {
- deg_debug_fprintf(ctx, ",lhead=\"cluster_%p\"", head);
+ dot::Cluster *head_cluster = ctx.clusters_map.lookup_default(head, nullptr);
+ if (head_cluster != nullptr && head_cluster->contains(dot_tail)) {
+ edge.attributes.set("lhead", head_cluster->name());
}
- deg_debug_fprintf(ctx, "];" NL);
- deg_debug_fprintf(ctx, NL);
}
}
-static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx, const Depsgraph *graph)
+static void deg_debug_graphviz_graph_nodes(DotExportContext &ctx, const Depsgraph *graph)
{
for (Node *node : graph->id_nodes) {
- deg_debug_graphviz_node(ctx, node);
+ deg_debug_graphviz_node(ctx, node, nullptr);
}
TimeSourceNode *time_source = graph->find_time_source();
if (time_source != nullptr) {
- deg_debug_graphviz_node(ctx, time_source);
+ deg_debug_graphviz_node(ctx, time_source, nullptr);
}
}
-static void deg_debug_graphviz_graph_relations(const DebugContext &ctx, const Depsgraph *graph)
+static void deg_debug_graphviz_graph_relations(DotExportContext &ctx, const Depsgraph *graph)
{
for (IDNode *id_node : graph->id_nodes) {
for (ComponentNode *comp_node : id_node->components.values()) {
@@ -592,27 +521,23 @@ void DEG_debug_relations_graphviz(const Depsgraph *graph, FILE *f, const char *l
const deg::Depsgraph *deg_graph = reinterpret_cast<const deg::Depsgraph *>(graph);
- deg::DebugContext ctx;
- ctx.file = f;
-
- deg::deg_debug_fprintf(ctx, "digraph depgraph {" NL);
- deg::deg_debug_fprintf(ctx, "rankdir=LR;" NL);
- deg::deg_debug_fprintf(ctx, "graph [");
- deg::deg_debug_fprintf(ctx, "compound=true");
- deg::deg_debug_fprintf(ctx, ",labelloc=\"t\"");
- deg::deg_debug_fprintf(ctx, ",fontsize=%f", deg::deg_debug_graphviz_graph_label_size);
- deg::deg_debug_fprintf(ctx, ",fontname=\"%s\"", deg::deg_debug_graphviz_fontname);
- deg::deg_debug_fprintf(ctx, ",label=\"%s\"", label);
- deg::deg_debug_fprintf(ctx, ",splines=ortho");
- deg::deg_debug_fprintf(ctx, ",overlap=scalexy"); // XXX: only when using neato
- deg::deg_debug_fprintf(ctx, "];" NL);
+ dot::DirectedGraph digraph;
+ deg::DotExportContext ctx{false, digraph};
+
+ digraph.set_rankdir(dot::Attr_rankdir::LeftToRight);
+ digraph.attributes.set("compound", "true");
+ digraph.attributes.set("labelloc", "t");
+ digraph.attributes.set("fontsize", deg::deg_debug_graphviz_graph_label_size);
+ digraph.attributes.set("fontname", deg::deg_debug_graphviz_fontname);
+ digraph.attributes.set("label", label);
+ digraph.attributes.set("splines", "ortho");
+ digraph.attributes.set("overlap", "scalexy");
deg::deg_debug_graphviz_graph_nodes(ctx, deg_graph);
deg::deg_debug_graphviz_graph_relations(ctx, deg_graph);
deg::deg_debug_graphviz_legend(ctx);
- deg::deg_debug_fprintf(ctx, "}" NL);
+ std::string dot_string = digraph.to_dot_string();
+ fprintf(f, "%s", dot_string.c_str());
}
-
-#undef NL
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
index 515b53297b9..16bdc2d6115 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_stats_gnuplot.cc
@@ -83,7 +83,7 @@ string gnuplotify_id_code(const string &name)
string gnuplotify_name(const string &name)
{
- string result = "";
+ string result;
const int length = name.length();
for (int i = 0; i < length; i++) {
const char ch = name[i];
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index c11d051e663..fb933cb38f3 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -43,12 +43,11 @@
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_debug.h"
-#include "builder/deg_builder.h"
-#include "builder/deg_builder_cache.h"
-#include "builder/deg_builder_cycle.h"
-#include "builder/deg_builder_nodes.h"
#include "builder/deg_builder_relations.h"
-#include "builder/deg_builder_transitive.h"
+#include "builder/pipeline_compositor.h"
+#include "builder/pipeline_from_ids.h"
+#include "builder/pipeline_render.h"
+#include "builder/pipeline_view_layer.h"
#include "intern/debug/deg_debug.h"
@@ -209,65 +208,14 @@ struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *node_handle)
/* ******************** */
/* Graph Building API's */
-static void graph_build_finalize_common(deg::Depsgraph *deg_graph, Main *bmain)
-{
- /* Detect and solve cycles. */
- deg::deg_graph_detect_cycles(deg_graph);
- /* Simplify the graph by removing redundant relations (to optimize
- * traversal later). */
- /* TODO: it would be useful to have an option to disable this in cases where
- * it is causing trouble. */
- if (G.debug_value == 799) {
- deg::deg_graph_transitive_reduction(deg_graph);
- }
- /* Store pointers to commonly used valuated datablocks. */
- deg_graph->scene_cow = (Scene *)deg_graph->get_cow_id(&deg_graph->scene->id);
- /* Flush visibility layer and re-schedule nodes for update. */
- deg::deg_graph_build_finalize(bmain, deg_graph);
- DEG_graph_on_visible_update(bmain, reinterpret_cast<::Depsgraph *>(deg_graph), false);
-#if 0
- if (!DEG_debug_consistency_check(deg_graph)) {
- printf("Consistency validation failed, ABORTING!\n");
- abort();
- }
-#endif
- /* Relations are up to date. */
- deg_graph->need_update = false;
-}
-
/* Build depsgraph for the given scene layer, and dump results in given graph container. */
void DEG_graph_build_from_view_layer(Depsgraph *graph,
Main *bmain,
Scene *scene,
ViewLayer *view_layer)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
- BLI_assert(deg_graph->scene == scene);
- BLI_assert(deg_graph->view_layer == view_layer);
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::ViewLayerBuilderPipeline builder(graph, bmain, scene, view_layer);
+ builder.build();
}
void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
@@ -275,170 +223,17 @@ void DEG_graph_build_for_render_pipeline(Depsgraph *graph,
Scene *scene,
ViewLayer *view_layer)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(deg_graph->scene == scene);
- deg_graph->is_render_pipeline_depsgraph = true;
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_scene_render(scene, view_layer);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation
- * order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_scene_render(scene, view_layer);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::RenderBuilderPipeline builder(graph, bmain, scene, view_layer);
+ builder.build();
}
void DEG_graph_build_for_compositor_preview(
Depsgraph *graph, Main *bmain, Scene *scene, struct ViewLayer *view_layer, bNodeTree *nodetree)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(deg_graph->scene == scene);
- deg_graph->is_render_pipeline_depsgraph = true;
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphNodeBuilder node_builder(bmain, deg_graph, &builder_cache);
- node_builder.begin_build();
- node_builder.build_scene_render(scene, view_layer);
- node_builder.build_nodetree(nodetree);
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation
- * order. */
- deg::DepsgraphRelationBuilder relation_builder(bmain, deg_graph, &builder_cache);
- relation_builder.begin_build();
- relation_builder.build_scene_render(scene, view_layer);
- relation_builder.build_nodetree(nodetree);
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::CompositorBuilderPipeline builder(graph, bmain, scene, view_layer, nodetree);
+ builder.build();
}
-/* Optimized builders for dependency graph built from a given set of IDs.
- *
- * General notes:
- *
- * - We pull in all bases if their objects are in the set of IDs. This allows to have proper
- * visibility and other flags assigned to the objects.
- * All other bases (the ones which points to object which is outside of the set of IDs) are
- * completely ignored.
- *
- * - Proxy groups pointing to objects which are outside of the IDs set are also ignored.
- * This way we avoid high-poly character body pulled into the dependency graph when it's coming
- * from a library into an animation file and the dependency graph constructed for a proxy rig. */
-
-namespace blender {
-namespace deg {
-namespace {
-
-class DepsgraphFromIDsFilter {
- public:
- DepsgraphFromIDsFilter(ID **ids, const int num_ids)
- {
- for (int i = 0; i < num_ids; ++i) {
- ids_.add(ids[i]);
- }
- }
-
- bool contains(ID *id)
- {
- return ids_.contains(id);
- }
-
- protected:
- Set<ID *> ids_;
-};
-
-class DepsgraphFromIDsNodeBuilder : public DepsgraphNodeBuilder {
- public:
- DepsgraphFromIDsNodeBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphNodeBuilder(bmain, graph, cache), filter_(ids, num_ids)
- {
- }
-
- virtual bool need_pull_base_into_graph(Base *base) override
- {
- if (!filter_.contains(&base->object->id)) {
- return false;
- }
- return DepsgraphNodeBuilder::need_pull_base_into_graph(base);
- }
-
- virtual void build_object_proxy_group(Object *object, bool is_visible) override
- {
- if (object->proxy_group == nullptr) {
- return;
- }
- if (!filter_.contains(&object->proxy_group->id)) {
- return;
- }
- DepsgraphNodeBuilder::build_object_proxy_group(object, is_visible);
- }
-
- protected:
- DepsgraphFromIDsFilter filter_;
-};
-
-class DepsgraphFromIDsRelationBuilder : public DepsgraphRelationBuilder {
- public:
- DepsgraphFromIDsRelationBuilder(
- Main *bmain, Depsgraph *graph, DepsgraphBuilderCache *cache, ID **ids, const int num_ids)
- : DepsgraphRelationBuilder(bmain, graph, cache), filter_(ids, num_ids)
- {
- }
-
- virtual bool need_pull_base_into_graph(Base *base) override
- {
- if (!filter_.contains(&base->object->id)) {
- return false;
- }
- return DepsgraphRelationBuilder::need_pull_base_into_graph(base);
- }
-
- virtual void build_object_proxy_group(Object *object) override
- {
- if (object->proxy_group == nullptr) {
- return;
- }
- if (!filter_.contains(&object->proxy_group->id)) {
- return;
- }
- DepsgraphRelationBuilder::build_object_proxy_group(object);
- }
-
- protected:
- DepsgraphFromIDsFilter filter_;
-};
-
-} // namespace
-} // namespace deg
-} // namespace blender
-
void DEG_graph_build_from_ids(Depsgraph *graph,
Main *bmain,
Scene *scene,
@@ -446,40 +241,8 @@ void DEG_graph_build_from_ids(Depsgraph *graph,
ID **ids,
const int num_ids)
{
- double start_time = 0.0;
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- start_time = PIL_check_seconds_timer();
- }
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(graph);
- /* Perform sanity checks. */
- BLI_assert(BLI_findindex(&scene->view_layers, view_layer) != -1);
- BLI_assert(deg_graph->scene == scene);
- BLI_assert(deg_graph->view_layer == view_layer);
- deg::DepsgraphBuilderCache builder_cache;
- /* Generate all the nodes in the graph first */
- deg::DepsgraphFromIDsNodeBuilder node_builder(bmain, deg_graph, &builder_cache, ids, num_ids);
- node_builder.begin_build();
- node_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids; ++i) {
- node_builder.build_id(ids[i]);
- }
- node_builder.end_build();
- /* Hook up relationships between operations - to determine evaluation order. */
- deg::DepsgraphFromIDsRelationBuilder relation_builder(
- bmain, deg_graph, &builder_cache, ids, num_ids);
- relation_builder.begin_build();
- relation_builder.build_view_layer(scene, view_layer, deg::DEG_ID_LINKED_DIRECTLY);
- for (int i = 0; i < num_ids; ++i) {
- relation_builder.build_id(ids[i]);
- }
- relation_builder.build_copy_on_write_relations();
- relation_builder.build_driver_relations();
- /* Finalize building. */
- graph_build_finalize_common(deg_graph, bmain);
- /* Finish statistics. */
- if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
- printf("Depsgraph built in %f seconds.\n", PIL_check_seconds_timer() - start_time);
- }
+ deg::FromIDsBuilderPipeline builder(graph, bmain, scene, view_layer, ids, num_ids);
+ builder.build();
}
/* Tag graph relations for update. */
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 814f467e3d5..048c0125f53 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -282,15 +282,14 @@ void DEG_iterator_objects_next(BLI_Iterator *iter)
if (deg_objects_dupli_iterator_next(iter)) {
return;
}
- else {
- verify_id_properties_freed(data);
- free_object_duplilist(data->dupli_list);
- data->dupli_parent = nullptr;
- data->dupli_list = nullptr;
- data->dupli_object_next = nullptr;
- data->dupli_object_current = nullptr;
- deg_invalidate_iterator_work_data(data);
- }
+
+ verify_id_properties_freed(data);
+ free_object_duplilist(data->dupli_list);
+ data->dupli_parent = nullptr;
+ data->dupli_list = nullptr;
+ data->dupli_object_next = nullptr;
+ data->dupli_object_current = nullptr;
+ deg_invalidate_iterator_work_data(data);
}
++data->id_node_index;
@@ -324,7 +323,7 @@ static void DEG_iterator_ids_step(BLI_Iterator *iter, deg::IDNode *id_node, bool
iter->skip = true;
return;
}
- else if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) {
+ if (only_updated && !(id_cow->recalc & ID_RECALC_ALL)) {
bNodeTree *ntree = ntreeFromID(id_cow);
/* Nodetree is considered part of the datablock. */
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index 848275eb899..4a2d47f9379 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -48,11 +48,8 @@
#include "BKE_idtype.h"
#include "BKE_node.h"
#include "BKE_scene.h"
-#include "BKE_workspace.h"
-
-#define new new_
#include "BKE_screen.h"
-#undef new
+#include "BKE_workspace.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
@@ -375,7 +372,7 @@ void graph_id_tag_update_single_flag(Main *bmain,
}
return;
}
- else if (tag == ID_RECALC_TIME) {
+ if (tag == ID_RECALC_TIME) {
if (graph != nullptr) {
graph->need_update_time = true;
}
@@ -432,7 +429,7 @@ string stringify_update_bitfield(int flag)
if (flag == 0) {
return "LEGACY_0";
}
- string result = "";
+ string result;
int current_flag = flag;
/* Special cases to avoid ALL flags form being split into
* individual bits. */
@@ -786,6 +783,7 @@ void DEG_graph_id_type_tag(Depsgraph *depsgraph, short id_type)
DEG_graph_id_type_tag(depsgraph, ID_LA);
DEG_graph_id_type_tag(depsgraph, ID_WO);
DEG_graph_id_type_tag(depsgraph, ID_SCE);
+ DEG_graph_id_type_tag(depsgraph, ID_SIM);
}
const int id_type_index = BKE_idtype_idcode_to_index(id_type);
deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index 6ca30a67f1f..1ede2cf914a 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -353,9 +353,8 @@ static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state)
if (G.debug & G_DEBUG_DEPSGRAPH_NO_THREADS) {
return BLI_task_pool_create_no_threads(state);
}
- else {
- return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH);
- }
+
+ return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH);
}
/**
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index c1e1ed3036d..d76f5991dac 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -120,6 +120,7 @@ union NestedIDHackTempStorage {
Scene scene;
Tex tex;
World world;
+ Simulation simulation;
};
/* Set nested owned ID pointers to nullptr. */
@@ -137,6 +138,7 @@ void nested_id_hack_discard_pointers(ID *id_cow)
SPECIAL_CASE(ID_MA, Material, nodetree)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree)
SPECIAL_CASE(ID_CU, Curve, key)
SPECIAL_CASE(ID_LT, Lattice, key)
@@ -185,6 +187,7 @@ const ID *nested_id_hack_get_discarded_pointers(NestedIDHackTempStorage *storage
SPECIAL_CASE(ID_MA, Material, nodetree, material)
SPECIAL_CASE(ID_TE, Tex, nodetree, tex)
SPECIAL_CASE(ID_WO, World, nodetree, world)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree, simulation)
SPECIAL_CASE(ID_CU, Curve, key, curve)
SPECIAL_CASE(ID_LT, Lattice, key, lattice)
@@ -224,6 +227,7 @@ void nested_id_hack_restore_pointers(const ID *old_id, ID *new_id)
SPECIAL_CASE(ID_SCE, Scene, nodetree)
SPECIAL_CASE(ID_TE, Tex, nodetree)
SPECIAL_CASE(ID_WO, World, nodetree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree)
SPECIAL_CASE(ID_CU, Curve, key)
SPECIAL_CASE(ID_LT, Lattice, key)
@@ -261,6 +265,7 @@ void ntree_hack_remap_pointers(const Depsgraph *depsgraph, ID *id_cow)
SPECIAL_CASE(ID_SCE, Scene, nodetree, bNodeTree)
SPECIAL_CASE(ID_TE, Tex, nodetree, bNodeTree)
SPECIAL_CASE(ID_WO, World, nodetree, bNodeTree)
+ SPECIAL_CASE(ID_SIM, Simulation, nodetree, bNodeTree)
SPECIAL_CASE(ID_CU, Curve, key, Key)
SPECIAL_CASE(ID_LT, Lattice, key, Key)
@@ -343,7 +348,7 @@ ViewLayer *get_original_view_layer(const Depsgraph *depsgraph, const IDNode *id_
if (id_node->linked_state == DEG_ID_LINKED_DIRECTLY) {
return depsgraph->view_layer;
}
- else if (id_node->linked_state == DEG_ID_LINKED_VIA_SET) {
+ if (id_node->linked_state == DEG_ID_LINKED_VIA_SET) {
Scene *scene_orig = reinterpret_cast<Scene *>(id_node->id_orig);
return BKE_view_layer_default_render(scene_orig);
}
@@ -377,7 +382,7 @@ void scene_remove_unused_view_layers(const Depsgraph *depsgraph,
}
return;
}
- else if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
+ if (id_node->linked_state == DEG_ID_LINKED_INDIRECTLY) {
/* Indirectly linked scenes means it's not an input scene and not a set scene, and is pulled
* via some driver. Such scenes should not have view layers after copy. */
view_layer_input = nullptr;
diff --git a/source/blender/depsgraph/intern/node/deg_node.cc b/source/blender/depsgraph/intern/node/deg_node.cc
index 9e386f13888..b10e66336dc 100644
--- a/source/blender/depsgraph/intern/node/deg_node.cc
+++ b/source/blender/depsgraph/intern/node/deg_node.cc
@@ -317,12 +317,11 @@ NodeClass Node::get_class() const
if (type == NodeType::OPERATION) {
return NodeClass::OPERATION;
}
- else if (type < NodeType::PARAMETERS) {
+ if (type < NodeType::PARAMETERS) {
return NodeClass::GENERIC;
}
- else {
- return NodeClass::COMPONENT;
- }
+
+ return NodeClass::COMPONENT;
}
/*******************************************************************************
diff --git a/source/blender/depsgraph/intern/node/deg_node_component.cc b/source/blender/depsgraph/intern/node/deg_node_component.cc
index cd82b7be050..2767513d6df 100644
--- a/source/blender/depsgraph/intern/node/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_component.cc
@@ -251,7 +251,7 @@ OperationNode *ComponentNode::get_entry_operation()
if (entry_operation) {
return entry_operation;
}
- else if (operations_map != nullptr && operations_map->size() == 1) {
+ if (operations_map != nullptr && operations_map->size() == 1) {
OperationNode *op_node = nullptr;
/* TODO(sergey): This is somewhat slow. */
for (OperationNode *tmp : operations_map->values()) {
@@ -261,7 +261,7 @@ OperationNode *ComponentNode::get_entry_operation()
entry_operation = op_node;
return op_node;
}
- else if (operations.size() == 1) {
+ if (operations.size() == 1) {
return operations[0];
}
return nullptr;
@@ -272,7 +272,7 @@ OperationNode *ComponentNode::get_exit_operation()
if (exit_operation) {
return exit_operation;
}
- else if (operations_map != nullptr && operations_map->size() == 1) {
+ if (operations_map != nullptr && operations_map->size() == 1) {
OperationNode *op_node = nullptr;
/* TODO(sergey): This is somewhat slow. */
for (OperationNode *tmp : operations_map->values()) {
@@ -282,7 +282,7 @@ OperationNode *ComponentNode::get_exit_operation()
exit_operation = op_node;
return op_node;
}
- else if (operations.size() == 1) {
+ if (operations.size() == 1) {
return operations[0];
}
return nullptr;
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index cfcd4e0c65a..f85b03dc517 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -64,6 +64,7 @@ set(SRC
intern/draw_color_management.c
intern/draw_common.c
intern/draw_debug.c
+ intern/draw_fluid.c
intern/draw_hair.c
intern/draw_instance_data.c
intern/draw_manager.c
@@ -186,10 +187,10 @@ set(LIB
)
data_to_c_simple(engines/eevee/shaders/ambient_occlusion_lib.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/default_frag.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/default_world_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/background_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/closure_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/common_uniforms_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/common_utiltex_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lights_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl SRC)
@@ -204,8 +205,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_grid_display_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_grid_fill_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_display_vert.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/lit_surface_frag.glsl SRC)
-data_to_c_simple(engines/eevee/shaders/lit_surface_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/lookdev_world_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/closure_lit_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_bloom_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
@@ -229,7 +230,6 @@ data_to_c_simple(engines/eevee/shaders/object_motion_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
-
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@@ -240,9 +240,14 @@ data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/cubemap_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/renderpass_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_geom.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/surface_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
@@ -288,6 +293,8 @@ data_to_c_simple(intern/shaders/common_globals_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_pointcloud_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_hair_refine_vert.glsl SRC)
+data_to_c_simple(intern/shaders/common_math_lib.glsl SRC)
+data_to_c_simple(intern/shaders/common_math_geom_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_view_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_fxaa_lib.glsl SRC)
data_to_c_simple(intern/shaders/common_smaa_lib.glsl SRC)
@@ -397,6 +404,13 @@ data_to_c_simple(engines/overlay/shaders/xray_fade_frag.glsl SRC)
list(APPEND INC
)
+if(WITH_MOD_FLUID)
+ list(APPEND INC
+ ../../../intern/mantaflow/extern
+ )
+ add_definitions(-DWITH_FLUID)
+endif()
+
if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
index 4a3cc36ddef..1d8082538a8 100644
--- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c
+++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c
@@ -54,24 +54,30 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_depth_of_field(const bool use_alpha)
{
- char *frag = BLI_string_joinN(datatoc_common_view_lib_glsl, datatoc_effect_dof_frag_glsl);
- e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen(
- frag,
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.dof_downsample_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_dof_frag_glsl,
+ lib,
use_alpha ? "#define USE_ALPHA_DOF\n"
"#define STEP_DOWNSAMPLE\n" :
"#define STEP_DOWNSAMPLE\n");
- e_data.dof_scatter_sh[use_alpha] = DRW_shader_create(datatoc_effect_dof_vert_glsl,
- NULL,
- frag,
- use_alpha ? "#define USE_ALPHA_DOF\n"
- "#define STEP_SCATTER\n" :
- "#define STEP_SCATTER\n");
- e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen(frag,
- use_alpha ?
- "#define USE_ALPHA_DOF\n"
- "#define STEP_RESOLVE\n" :
- "#define STEP_RESOLVE\n");
- MEM_freeN(frag);
+
+ e_data.dof_scatter_sh[use_alpha] = DRW_shader_create_with_shaderlib(
+ datatoc_effect_dof_vert_glsl,
+ NULL,
+ datatoc_effect_dof_frag_glsl,
+ lib,
+ use_alpha ? "#define USE_ALPHA_DOF\n"
+ "#define STEP_SCATTER\n" :
+ "#define STEP_SCATTER\n");
+
+ e_data.dof_resolve_sh[use_alpha] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_dof_frag_glsl,
+ lib,
+ use_alpha ? "#define USE_ALPHA_DOF\n"
+ "#define STEP_RESOLVE\n" :
+ "#define STEP_RESOLVE\n");
}
int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata),
@@ -255,7 +261,7 @@ void EEVEE_depth_of_field_draw(EEVEE_Data *vedata)
/* Depth Of Field */
if ((effects->enabled_effects & EFFECT_DOF) != 0) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Downsample */
GPU_framebuffer_bind(fbl->dof_down_fb);
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index f6e74c6822c..365ba0afaac 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -138,7 +138,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
const float *viewport_size = DRW_viewport_size_get();
- int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
/* Shaders */
if (!e_data.downsample_sh) {
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index a142648d08d..72f008ea66a 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -32,6 +32,8 @@
#include "DNA_world_types.h"
+#include "IMB_imbuf.h"
+
#include "eevee_private.h"
#include "eevee_engine.h" /* own include */
@@ -215,10 +217,10 @@ static void eevee_draw_scene(void *vedata)
}
while (loop_len--) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float clear_depth = 1.0f;
uint clear_stencil = 0x0;
- uint primes[3] = {2, 3, 7};
+ const uint primes[3] = {2, 3, 7};
double offset[3] = {0.0, 0.0, 0.0};
double r[3];
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index 19325729114..6d2577d5b78 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -863,7 +863,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
/* HACK: set txl->color but unset it before Draw Manager frees it. */
txl->color = lbake->rt_color;
- int viewport_size[2] = {
+ const int viewport_size[2] = {
GPU_texture_width(txl->color),
GPU_texture_height(txl->color),
};
@@ -1021,9 +1021,8 @@ static void compute_cell_id(EEVEE_LightGrid *egrid,
if (visited_cells == cell_idx) {
return;
}
- else {
- visited_cells++;
- }
+
+ visited_cells++;
}
}
}
@@ -1032,7 +1031,7 @@ static void compute_cell_id(EEVEE_LightGrid *egrid,
BLI_assert(0);
}
-static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, int local_cell[3], float r_pos[3])
+static void grid_loc_to_world_loc(EEVEE_LightGrid *egrid, const int local_cell[3], float r_pos[3])
{
copy_v3_v3(r_pos, egrid->corner);
madd_v3_v3fl(r_pos, egrid->increment_x, local_cell[0]);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index a2f7686619f..0f4a9dc79b6 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -335,38 +335,28 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
{
DRW_PASS_CREATE(psl->probe_background, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
+ EEVEE_lookdev_cache_init(vedata, sldata, psl->probe_background, pinfo, &grp);
- Scene *scene = draw_ctx->scene;
- World *wo = scene->world;
-
- /* LookDev */
- EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->probe_background, wo, pinfo);
+ if (grp == NULL) {
+ Scene *scene = draw_ctx->scene;
+ World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
- if (!grp && wo) {
- struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_WORLD_PROBE);
+ const int options = VAR_WORLD_BACKGROUND | VAR_WORLD_PROBE;
+ struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->probe_background);
DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- DRW_shgroup_call(grp, geom, NULL);
}
- /* Fallback if shader fails or if not using nodetree. */
- if (grp == NULL) {
- grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background);
- DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- DRW_shgroup_call(grp, geom, NULL);
- }
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
if (DRW_state_draw_support()) {
@@ -1122,7 +1112,7 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata,
#if defined(IRRADIANCE_SH_L2)
int size[2] = {3, 3};
#elif defined(IRRADIANCE_HL2)
- int size[2] = {3, 2};
+ const int size[2] = {3, 2};
pinfo->samples_len = 1024.0f;
#endif
diff --git a/source/blender/draw/engines/eevee/eevee_lookdev.c b/source/blender/draw/engines/eevee/eevee_lookdev.c
index b044213e029..f79d90500bd 100644
--- a/source/blender/draw/engines/eevee/eevee_lookdev.c
+++ b/source/blender/draw/engines/eevee/eevee_lookdev.c
@@ -97,10 +97,9 @@ static void eevee_lookdev_hdri_preview_init(EEVEE_Data *vedata, EEVEE_ViewLayerD
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
- DRWShadingGroup **r_grp,
DRWPass *pass,
- World *UNUSED(world),
- EEVEE_LightProbesInfo *pinfo)
+ EEVEE_LightProbesInfo *pinfo,
+ DRWShadingGroup **r_shgrp)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
@@ -153,89 +152,88 @@ void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
const View3DShading *shading = &v3d->shading;
StudioLight *sl = BKE_studiolight_find(shading->lookdev_light,
STUDIOLIGHT_ORIENTATIONS_MATERIAL_MODE);
- if (sl && (sl->flag & STUDIOLIGHT_TYPE_WORLD)) {
- GPUShader *shader = probe_render ? EEVEE_shaders_default_studiolight_sh_get() :
- EEVEE_shaders_background_studiolight_sh_get();
+ if (sl == NULL || (sl->flag & STUDIOLIGHT_TYPE_WORLD) == 0) {
+ return;
+ }
+
+ GPUShader *shader = probe_render ? EEVEE_shaders_studiolight_probe_sh_get() :
+ EEVEE_shaders_studiolight_background_sh_get();
- const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- int cube_res = scene_eval->eevee.gi_cubemap_resolution;
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+ int cube_res = scene_eval->eevee.gi_cubemap_resolution;
- /* If one of the component is missing we start from scratch. */
- if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
- (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
- (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
- eevee_lookdev_lightcache_delete(vedata);
- }
+ /* If one of the component is missing we start from scratch. */
+ if ((stl->lookdev_grid_data == NULL) || (stl->lookdev_cube_data == NULL) ||
+ (txl->lookdev_grid_tx == NULL) || (txl->lookdev_cube_tx == NULL) ||
+ (g_data->light_cache && g_data->light_cache->ref_res != cube_res)) {
+ eevee_lookdev_lightcache_delete(vedata);
+ }
- if (stl->lookdev_lightcache == NULL) {
+ if (stl->lookdev_lightcache == NULL) {
#if defined(IRRADIANCE_SH_L2)
- int grid_res = 4;
+ int grid_res = 4;
#elif defined(IRRADIANCE_HL2)
- int grid_res = 4;
+ int grid_res = 4;
#endif
- stl->lookdev_lightcache = EEVEE_lightcache_create(
- 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
-
- /* XXX: Fix memleak. TODO find out why. */
- MEM_SAFE_FREE(stl->lookdev_cube_mips);
-
- /* We do this to use a special light cache for lookdev.
- * This light-cache needs to be per viewport. But we need to
- * have correct freeing when the viewport is closed. So we
- * need to reference all textures to the txl and the memblocks
- * to the stl. */
- stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
- stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
- stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
- txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
- txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
- }
-
- g_data->light_cache = stl->lookdev_lightcache;
-
- DRWShadingGroup *grp = *r_grp = DRW_shgroup_create(shader, pass);
- axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
- DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
-
- if (probe_render) {
- DRW_shgroup_uniform_float_copy(
- grp, "studioLightIntensity", shading->studiolight_intensity);
- BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
- DRW_shgroup_uniform_texture(grp, "image", sl->equirect_radiance_gputexture);
- /* Do not fadeout when doing probe rendering, only when drawing the background */
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
- }
- else {
- float background_alpha = g_data->background_alpha * shading->studiolight_background;
- float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
- DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
- DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
- DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
- }
-
- DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
-
- /* Do we need to recalc the lightprobes? */
- if (g_data->studiolight_index != sl->index ||
- g_data->studiolight_rot_z != shading->studiolight_rot_z ||
- g_data->studiolight_intensity != shading->studiolight_intensity ||
- g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
- g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
- g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
- stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
- g_data->studiolight_index = sl->index;
- g_data->studiolight_rot_z = shading->studiolight_rot_z;
- g_data->studiolight_intensity = shading->studiolight_intensity;
- g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
- g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
- g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
- }
+ stl->lookdev_lightcache = EEVEE_lightcache_create(
+ 1, 1, cube_res, 8, (int[3]){grid_res, grid_res, 1});
+
+ /* XXX: Fix memleak. TODO find out why. */
+ MEM_SAFE_FREE(stl->lookdev_cube_mips);
+
+ /* We do this to use a special light cache for lookdev.
+ * This light-cache needs to be per viewport. But we need to
+ * have correct freeing when the viewport is closed. So we
+ * need to reference all textures to the txl and the memblocks
+ * to the stl. */
+ stl->lookdev_grid_data = stl->lookdev_lightcache->grid_data;
+ stl->lookdev_cube_data = stl->lookdev_lightcache->cube_data;
+ stl->lookdev_cube_mips = stl->lookdev_lightcache->cube_mips;
+ txl->lookdev_grid_tx = stl->lookdev_lightcache->grid_tx.tex;
+ txl->lookdev_cube_tx = stl->lookdev_lightcache->cube_tx.tex;
+ }
+
+ g_data->light_cache = stl->lookdev_lightcache;
+
+ DRWShadingGroup *grp = DRW_shgroup_create(shader, pass);
+ axis_angle_to_mat3_single(g_data->studiolight_matrix, 'Z', shading->studiolight_rot_z);
+ DRW_shgroup_uniform_mat3(grp, "StudioLightMatrix", g_data->studiolight_matrix);
+
+ if (probe_render) {
+ /* Avoid artifact with equirectangular mapping. */
+ eGPUSamplerState state = (GPU_SAMPLER_FILTER | GPU_SAMPLER_REPEAT_S);
+ DRW_shgroup_uniform_float_copy(grp, "studioLightIntensity", shading->studiolight_intensity);
+ BKE_studiolight_ensure_flag(sl, STUDIOLIGHT_EQUIRECT_RADIANCE_GPUTEXTURE);
+ DRW_shgroup_uniform_texture_ex(grp, "studioLight", sl->equirect_radiance_gputexture, state);
+ /* Do not fadeout when doing probe rendering, only when drawing the background */
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f);
+ }
+ else {
+ float background_alpha = g_data->background_alpha * shading->studiolight_background;
+ float studiolight_blur = powf(shading->studiolight_blur, 2.5f);
+ DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", background_alpha);
+ DRW_shgroup_uniform_float_copy(grp, "studioLightBlur", studiolight_blur);
+ DRW_shgroup_uniform_texture(grp, "probeCubes", txl->lookdev_cube_tx);
+ }
+
+ /* Common UBOs are setup latter. */
+ *r_shgrp = grp;
+
+ /* Do we need to recalc the lightprobes? */
+ if (g_data->studiolight_index != sl->index ||
+ g_data->studiolight_rot_z != shading->studiolight_rot_z ||
+ g_data->studiolight_intensity != shading->studiolight_intensity ||
+ g_data->studiolight_cubemap_res != scene->eevee.gi_cubemap_resolution ||
+ g_data->studiolight_glossy_clamp != scene->eevee.gi_glossy_clamp ||
+ g_data->studiolight_filter_quality != scene->eevee.gi_filter_quality) {
+ stl->lookdev_lightcache->flag |= LIGHTCACHE_UPDATE_WORLD;
+ g_data->studiolight_index = sl->index;
+ g_data->studiolight_rot_z = shading->studiolight_rot_z;
+ g_data->studiolight_intensity = shading->studiolight_intensity;
+ g_data->studiolight_cubemap_res = scene->eevee.gi_cubemap_resolution;
+ g_data->studiolight_glossy_clamp = scene->eevee.gi_glossy_clamp;
+ g_data->studiolight_filter_quality = scene->eevee.gi_filter_quality;
}
}
}
@@ -247,7 +245,7 @@ static void eevee_lookdev_apply_taa(const EEVEE_EffectsInfo *effects,
if (DRW_state_is_image_render() || ((effects->enabled_effects & EFFECT_TAA) != 0)) {
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
- uint ht_primes[2] = {2, 3};
+ const uint ht_primes[2] = {2, 3};
float ofs[2];
BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample, ht_point);
diff --git a/source/blender/draw/engines/eevee/eevee_lut_gen.c b/source/blender/draw/engines/eevee/eevee_lut_gen.c
index 6cee05bf015..9b07a6908c3 100644
--- a/source/blender/draw/engines/eevee/eevee_lut_gen.c
+++ b/source/blender/draw/engines/eevee/eevee_lut_gen.c
@@ -31,6 +31,8 @@
#include "BLI_rand.h"
#include "BLI_string_utils.h"
+#include "eevee_private.h"
+
extern char datatoc_bsdf_lut_frag_glsl[];
extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
@@ -45,15 +47,13 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
static float samples_len = 8192.0f;
static float inv_samples_len = 1.0f / 8192.0f;
- char *lib_str = BLI_string_joinN(datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- struct GPUShader *sh = DRW_shader_create_with_lib(datatoc_lightprobe_vert_glsl,
- datatoc_lightprobe_geom_glsl,
- datatoc_bsdf_lut_frag_glsl,
- lib_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n");
+ struct GPUShader *sh = DRW_shader_create_with_shaderlib(datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_bsdf_lut_frag_glsl,
+ lib,
+ "#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -105,16 +105,10 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
static float a2 = 0.0f;
static float inv_samples_len = 1.0f / 8192.0f;
- char *frag_str = BLI_string_joinN(
- datatoc_bsdf_common_lib_glsl, datatoc_bsdf_sampling_lib_glsl, datatoc_btdf_lut_frag_glsl);
-
- struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
- "#define HAMMERSLEY_SIZE 8192\n"
- "#define BRDF_LUT_SIZE 64\n"
- "#define NOISE_SIZE 64\n"
- "#define LUT_SIZE 64\n");
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- MEM_freeN(frag_str);
+ struct GPUShader *sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_btdf_lut_frag_glsl, lib, "#define HAMMERSLEY_SIZE 8192\n");
DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
@@ -194,4 +188,4 @@ static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
MEM_freeN(data);
return tex;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 143945b637a..fb07208be47 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -56,37 +56,6 @@ static struct {
float noise_offsets[3];
} e_data = {NULL}; /* Engine data */
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_lightprobe_lib_glsl[];
-extern char datatoc_ambient_occlusion_lib_glsl[];
-extern char datatoc_prepass_frag_glsl[];
-extern char datatoc_prepass_vert_glsl[];
-extern char datatoc_default_frag_glsl[];
-extern char datatoc_default_world_frag_glsl[];
-extern char datatoc_ltc_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_common_hair_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_irradiance_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_lit_surface_frag_glsl[];
-extern char datatoc_lit_surface_vert_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
-extern char datatoc_ssr_lib_glsl[];
-extern char datatoc_shadow_vert_glsl[];
-extern char datatoc_lightprobe_geom_glsl[];
-extern char datatoc_lightprobe_vert_glsl[];
-extern char datatoc_background_vert_glsl[];
-extern char datatoc_update_noise_frag_glsl[];
-extern char datatoc_volumetric_vert_glsl[];
-extern char datatoc_volumetric_geom_glsl[];
-extern char datatoc_volumetric_frag_glsl[];
-extern char datatoc_volumetric_lib_glsl[];
-extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
-
typedef struct EeveeMaterialCache {
struct DRWShadingGroup *depth_grp;
struct DRWShadingGroup *shading_grp;
@@ -238,46 +207,6 @@ void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const d
DRW_draw_pass(psl->update_noise_pass);
}
-void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4])
-{
- /* view vectors for the corners of the view frustum.
- * Can be used to recreate the world space position easily */
- float view_vecs[4][4] = {
- {-1.0f, -1.0f, -1.0f, 1.0f},
- {1.0f, -1.0f, -1.0f, 1.0f},
- {-1.0f, 1.0f, -1.0f, 1.0f},
- {-1.0f, -1.0f, 1.0f, 1.0f},
- };
-
- /* convert the view vectors to view space */
- const bool is_persp = (winmat[3][3] == 0.0f);
- for (int i = 0; i < 4; i++) {
- mul_project_m4_v3(invproj, view_vecs[i]);
- /* normalized trick see:
- * http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
- if (is_persp) {
- /* Divide XY by Z. */
- mul_v2_fl(view_vecs[i], 1.0f / view_vecs[i][2]);
- }
- }
-
- /**
- * If ortho : view_vecs[0] is the near-bottom-left corner of the frustum and
- * view_vecs[1] is the vector going from the near-bottom-left corner to
- * the far-top-right corner.
- * If Persp : view_vecs[0].xy and view_vecs[1].xy are respectively the bottom-left corner
- * when Z = 1, and top-left corner if Z = 1.
- * view_vecs[0].z the near clip distance and view_vecs[1].z is the (signed)
- * distance from the near plane to the far clip plane.
- */
- copy_v4_v4(r_viewvecs[0], view_vecs[0]);
-
- /* we need to store the differences */
- r_viewvecs[1][0] = view_vecs[1][0] - view_vecs[0][0];
- r_viewvecs[1][1] = view_vecs[2][1] - view_vecs[0][1];
- r_viewvecs[1][2] = view_vecs[3][2] - view_vecs[0][2];
-}
-
void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
EEVEE_StorageList *stl,
@@ -305,15 +234,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
}
{
- /* Update view_vecs */
- float invproj[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, invproj, true);
-
- EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
- }
-
- {
/* Update noise Framebuffer. */
GPU_framebuffer_ensure_config(
&fbl->update_noise_fb,
@@ -391,39 +311,28 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
DRW_PASS_CREATE(psl->background_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
- struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = NULL;
+ EEVEE_lookdev_cache_init(vedata, sldata, psl->background_ps, NULL, &grp);
- Scene *scene = draw_ctx->scene;
- World *wo = scene->world;
-
- EEVEE_lookdev_cache_init(vedata, sldata, &grp, psl->background_ps, wo, NULL);
+ if (grp == NULL) {
+ Scene *scene = draw_ctx->scene;
+ World *world = (scene->world) ? scene->world : EEVEE_world_default_get();
- if (!grp && wo) {
- struct GPUMaterial *gpumat = EEVEE_material_get(
- vedata, scene, NULL, wo, VAR_WORLD_BACKGROUND);
+ const int options = VAR_WORLD_BACKGROUND;
+ struct GPUMaterial *gpumat = EEVEE_material_get(vedata, scene, NULL, world, options);
grp = DRW_shgroup_material_create(gpumat, psl->background_ps);
DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
- DRW_shgroup_call(grp, geom, NULL);
}
- /* Fallback if shader fails or if not using nodetree. */
- if (grp == NULL) {
- GPUShader *sh = EEVEE_shaders_default_background_sh_get();
- grp = DRW_shgroup_create(sh, psl->background_ps);
- DRW_shgroup_uniform_vec3(grp, "color", G_draw.block.colorBackground, 1);
- DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- DRW_shgroup_call(grp, geom, NULL);
- }
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block_ref(grp, "renderpass_block", &stl->g_data->renderpass_ubo);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
#define EEVEE_PASS_CREATE(pass, state) \
@@ -574,9 +483,8 @@ static EeveeMaterialCache material_opaque(EEVEE_Data *vedata,
if (BLI_ghash_ensure_p(pd->material_hash, key, (void ***)&emc_p)) {
return **emc_p;
}
- else {
- *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
- }
+
+ *emc_p = emc = BLI_memblock_alloc(sldata->material_cache);
material_shadow(vedata, sldata, ma, is_hair, emc);
@@ -999,7 +907,7 @@ static void material_renderpass_init(EEVEE_FramebufferList *fbl,
DRW_texture_ensure_fullscreen_2d(output_tx, format, 0);
/* Clear texture. */
if (do_clear) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* TODO(fclem) replace by GPU_texture_clear once it is fast. */
GPU_framebuffer_texture_attach(fbl->material_accum_fb, *output_tx, 0, 0);
GPU_framebuffer_bind(fbl->material_accum_fb);
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index 1cedd334d67..cfac6cc4d62 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -53,17 +53,13 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_PrivateData *g_data = stl->g_data;
Scene *scene = draw_ctx->scene;
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
if (e_data.mist_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_mist_frag_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- e_data.mist_sh = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
-
- MEM_freeN(frag_str);
+ e_data.mist_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_mist_frag_glsl, lib, "#define FIRST_PASS\n");
}
/* Create FrameBuffer. */
@@ -98,11 +94,11 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
else {
- float near = -sldata->common_data.view_vecs[0][2];
- float range = sldata->common_data.view_vecs[1][2];
+ float near = DRW_view_near_distance_get(NULL);
+ float far = DRW_view_far_distance_get(NULL);
/* Fallback */
g_data->mist_start = near;
- g_data->mist_inv_dist = 1.0f / fabsf(range);
+ g_data->mist_inv_dist = 1.0f / fabsf(far - near);
g_data->mist_falloff = 1.0f;
}
diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c
index 400b309de07..2a315927015 100644
--- a/source/blender/draw/engines/eevee/eevee_motion_blur.c
+++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c
@@ -69,27 +69,23 @@ extern char datatoc_common_view_lib_glsl[];
static void eevee_create_shader_motion_blur(void)
{
- e_data.motion_blur_sh = DRW_shader_create_fullscreen(
- datatoc_effect_motion_blur_frag_glsl,
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
- e_data.motion_blur_object_sh = DRW_shader_create_with_lib(datatoc_object_motion_vert_glsl,
- NULL,
- datatoc_object_motion_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(
- datatoc_effect_velocity_tile_frag_glsl,
- "#define TILE_GATHER\n"
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
+#define TILE_SIZE_STR "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n"
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+ e_data.motion_blur_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_motion_blur_frag_glsl, lib, TILE_SIZE_STR);
+ e_data.motion_blur_object_sh = DRW_shader_create_with_shaderlib(
+ datatoc_object_motion_vert_glsl, NULL, datatoc_object_motion_frag_glsl, lib, NULL);
+
+ e_data.motion_blur_hair_sh = DRW_shader_create_with_shaderlib(datatoc_object_motion_vert_glsl,
+ NULL,
+ datatoc_object_motion_frag_glsl,
+ lib,
+ "#define HAIR\n");
+
+ e_data.velocity_tiles_sh = DRW_shader_create_fullscreen(datatoc_effect_velocity_tile_frag_glsl,
+ "#define TILE_GATHER\n" TILE_SIZE_STR);
e_data.velocity_tiles_expand_sh = DRW_shader_create_fullscreen(
- datatoc_effect_velocity_tile_frag_glsl,
- "#define TILE_EXPANSION\n"
- "#define EEVEE_VELOCITY_TILE_SIZE " STRINGIFY(EEVEE_VELOCITY_TILE_SIZE) "\n");
-
- char *vert = BLI_string_joinN(datatoc_common_hair_lib_glsl, datatoc_object_motion_vert_glsl);
- e_data.motion_blur_hair_sh = DRW_shader_create_with_lib(
- vert, NULL, datatoc_object_motion_frag_glsl, datatoc_common_view_lib_glsl, "#define HAIR\n");
- MEM_freeN(vert);
+ datatoc_effect_velocity_tile_frag_glsl, "#define TILE_EXPANSION\n" TILE_SIZE_STR);
}
int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -121,8 +117,10 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
}
const float *fs_size = DRW_viewport_size_get();
- int tx_size[2] = {1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE),
- 1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE)};
+ const int tx_size[2] = {
+ 1 + ((int)fs_size[0] / EEVEE_VELOCITY_TILE_SIZE),
+ 1 + ((int)fs_size[1] / EEVEE_VELOCITY_TILE_SIZE),
+ };
effects->velocity_tiles_x_tx = DRW_texture_pool_query_2d(
tx_size[0], fs_size[1], GPU_RGBA16, &draw_engine_eevee_type);
@@ -177,8 +175,10 @@ void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
const float *fs_size = DRW_viewport_size_get();
- int tx_size[2] = {GPU_texture_width(effects->velocity_tiles_tx),
- GPU_texture_height(effects->velocity_tiles_tx)};
+ const int tx_size[2] = {
+ GPU_texture_width(effects->velocity_tiles_tx),
+ GPU_texture_height(effects->velocity_tiles_tx),
+ };
eevee_motion_blur_sync_camera(vedata);
@@ -484,16 +484,15 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata)
GPU_VERTBUF_DISCARD_SAFE(mb_geom->vbo[MB_NEXT]);
break;
}
+
+ /* Modify the batch to include the previous & next position. */
+ if (i == MB_PREV) {
+ GPU_batch_vertbuf_add_ex(batch, vbo, true);
+ mb_geom->vbo[i] = NULL;
+ }
else {
- /* Modify the batch to include the previous & next position. */
- if (i == MB_PREV) {
- GPU_batch_vertbuf_add_ex(batch, vbo, true);
- mb_geom->vbo[i] = NULL;
- }
- else {
- /* This VBO can be reuse by next time step. Don't pass ownership. */
- GPU_batch_vertbuf_add_ex(batch, vbo, false);
- }
+ /* This VBO can be reuse by next time step. Don't pass ownership. */
+ GPU_batch_vertbuf_add_ex(batch, vbo, false);
}
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index a075210967c..9aae801197f 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -53,17 +53,14 @@ extern char datatoc_effect_gtao_frag_glsl[];
static void eevee_create_shader_occlusion(void)
{
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_effect_gtao_frag_glsl);
-
- e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
- e_data.gtao_layer_sh = DRW_shader_create_fullscreen(frag_str, "#define LAYERED_DEPTH\n");
- e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
-
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.gtao_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, NULL);
+ e_data.gtao_layer_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, "#define LAYERED_DEPTH\n");
+ e_data.gtao_debug_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_gtao_frag_glsl, lib, "#define DEBUG_AO\n");
}
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
@@ -77,7 +74,7 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (!e_data.dummy_horizon_tx) {
- float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float pixel[4] = {0.0f, 0.0f, 0.0f, 0.0f};
e_data.dummy_horizon_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, pixel);
}
@@ -146,7 +143,7 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Should be enough precision for many samples. */
DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 829d26ef876..34cd22ad13c 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -164,7 +164,7 @@ enum {
VAR_MAT_MESH = (1 << 0),
VAR_MAT_VOLUME = (1 << 1),
VAR_MAT_HAIR = (1 << 2),
- VAR_MAT_PROBE = (1 << 3),
+ /* VAR_MAT_PROBE = (1 << 3), UNUSED */
VAR_MAT_BLEND = (1 << 4),
VAR_MAT_LOOKDEV = (1 << 5),
VAR_MAT_HOLDOUT = (1 << 6),
@@ -748,7 +748,6 @@ typedef struct EEVEE_EffectsInfo {
* - sizeof(bool) == sizeof(int) in GLSL so use int in C */
typedef struct EEVEE_CommonUniformBuffer {
float prev_persmat[4][4]; /* mat4 */
- float view_vecs[2][4]; /* vec4[2] */
float mip_ratio[10][4]; /* vec2[10] */
/* Ambient Occlusion */
/* -- 16 byte aligned -- */
@@ -1006,7 +1005,6 @@ void EEVEE_object_hair_cache_populate(EEVEE_Data *vedata,
void EEVEE_materials_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_materials_free(void);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
-void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -1062,15 +1060,14 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4]);
/* eevee_shaders.c */
void EEVEE_shaders_lightprobe_shaders_init(void);
void EEVEE_shaders_material_shaders_init(void);
+struct DRWShaderLibrary *EEVEE_shader_lib_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void);
-struct GPUShader *EEVEE_shaders_probe_default_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_filter_visibility_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_fill_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void);
-struct GPUShader *EEVEE_shaders_default_studiolight_sh_get(void);
-struct GPUShader *EEVEE_shaders_default_background_sh_get(void);
-struct GPUShader *EEVEE_shaders_background_studiolight_sh_get(void);
+struct GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void);
+struct GPUShader *EEVEE_shaders_studiolight_background_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void);
struct GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void);
@@ -1082,6 +1079,7 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo);
Material *EEVEE_material_default_diffuse_get(void);
Material *EEVEE_material_default_glossy_get(void);
Material *EEVEE_material_default_error_get(void);
+World *EEVEE_world_default_get(void);
struct GPUMaterial *EEVEE_material_default_get(struct Scene *scene, Material *ma, int options);
struct GPUMaterial *EEVEE_material_get(
EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options);
@@ -1308,10 +1306,9 @@ void EEVEE_render_update_passes(struct RenderEngine *engine,
/** eevee_lookdev.c */
void EEVEE_lookdev_cache_init(EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata,
- DRWShadingGroup **grp,
DRWPass *pass,
- struct World *world,
- EEVEE_LightProbesInfo *pinfo);
+ EEVEE_LightProbesInfo *pinfo,
+ DRWShadingGroup **r_shgrp);
void EEVEE_lookdev_draw(EEVEE_Data *vedata);
/** eevee_engine.c */
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index b6b8833b1da..62698bc5da3 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -93,8 +93,10 @@ bool EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
copy_v4_fl4(camtexcofac, 1.0f, 1.0f, 0.0f, 0.0f);
}
- int final_res[2] = {size_orig[0] + g_data->overscan_pixels * 2.0f,
- size_orig[1] + g_data->overscan_pixels * 2.0f};
+ const int final_res[2] = {
+ size_orig[0] + g_data->overscan_pixels * 2.0f,
+ size_orig[1] + g_data->overscan_pixels * 2.0f,
+ };
int max_dim = max_ii(final_res[0], final_res[1]);
if (max_dim > GPU_max_texture_size()) {
@@ -523,10 +525,10 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
}
while (render_samples < tot_sample && !RE_engine_test_break(engine)) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float clear_depth = 1.0f;
uint clear_stencil = 0x00;
- uint primes[3] = {2, 3, 7};
+ const uint primes[3] = {2, 3, 7};
double offset[3] = {0.0, 0.0, 0.0};
double r[3];
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index be771d7cf42..089d8b7a287 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -199,12 +199,10 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0;
if (needs_post_processing) {
if (e_data.postprocess_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_renderpass_postprocess_frag_glsl);
- e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL);
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.postprocess_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_renderpass_postprocess_frag_glsl, lib, NULL);
}
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
diff --git a/source/blender/draw/engines/eevee/eevee_sampling.c b/source/blender/draw/engines/eevee/eevee_sampling.c
index 5e951928c5a..253dae79902 100644
--- a/source/blender/draw/engines/eevee/eevee_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_sampling.c
@@ -34,7 +34,7 @@ void EEVEE_sample_ball(int sample_ofs, float radius, float rsample[3])
{
double ht_point[3];
double ht_offset[3] = {0.0, 0.0, 0.0};
- uint ht_primes[3] = {2, 3, 7};
+ const uint ht_primes[3] = {2, 3, 7};
BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point);
@@ -65,7 +65,7 @@ void EEVEE_sample_rectangle(int sample_ofs,
{
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
- uint ht_primes[2] = {2, 3};
+ const uint ht_primes[2] = {2, 3};
BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point);
@@ -91,7 +91,7 @@ void EEVEE_sample_ellipse(int sample_ofs,
{
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
- uint ht_primes[2] = {2, 3};
+ const uint ht_primes[2] = {2, 3};
BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point);
@@ -114,7 +114,7 @@ void EEVEE_random_rotation_m4(int sample_ofs, float scale, float r_mat[4][4])
{
double ht_point[3];
double ht_offset[3] = {0.0, 0.0, 0.0};
- uint ht_primes[3] = {2, 3, 5};
+ const uint ht_primes[3] = {2, 3, 5};
BLI_halton_3d(ht_primes, ht_offset, sample_ofs, ht_point);
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 32d758dba4b..88029c2e940 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -48,30 +48,12 @@ static struct {
struct GPUTexture *depth_src;
} e_data = {{NULL}}; /* Engine data */
-extern char datatoc_ambient_occlusion_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
extern char datatoc_effect_ssr_frag_glsl[];
-extern char datatoc_lightprobe_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
{
if (e_data.ssr_sh[options] == NULL) {
- char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_effect_ssr_frag_glsl);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
DynStr *ds_defines = BLI_dynstr_new();
BLI_dynstr_append(ds_defines, SHADER_DEFINES);
@@ -91,9 +73,9 @@ static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines);
BLI_dynstr_free(ds_defines);
- e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str);
+ e_data.ssr_sh[options] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_ssr_frag_glsl, lib, ssr_define_str);
- MEM_freeN(ssr_shader_str);
MEM_freeN(ssr_define_str);
}
@@ -156,7 +138,7 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
const int divisor = (effects->reflection_trace_full) ? 1 : 2;
int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
- int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
+ const int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
const bool high_qual_input = true; /* TODO dither low quality input */
const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8;
@@ -348,7 +330,7 @@ void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F;
diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c
index 09e74c84948..5f125d395d3 100644
--- a/source/blender/draw/engines/eevee/eevee_shaders.c
+++ b/source/blender/draw/engines/eevee/eevee_shaders.c
@@ -28,6 +28,8 @@
#include "BLI_dynstr.h"
#include "BLI_string_utils.h"
+#include "DNA_world_types.h"
+
#include "MEM_guardedalloc.h"
#include "GPU_material.h"
@@ -40,19 +42,17 @@
static const char *filter_defines = "#define HAMMERSLEY_SIZE " STRINGIFY(HAMMERSLEY_SIZE) "\n"
#if defined(IRRADIANCE_SH_L2)
- "#define IRRADIANCE_SH_L2\n"
-#elif defined(IRRADIANCE_CUBEMAP)
- "#define IRRADIANCE_CUBEMAP\n"
+ "#define IRRADIANCE_SH_L2\n";
#elif defined(IRRADIANCE_HL2)
- "#define IRRADIANCE_HL2\n"
+ "#define IRRADIANCE_HL2\n";
#endif
- "#define NOISE_SIZE 64\n";
static struct {
+ /* Lookdev */
+ struct GPUShader *studiolight_probe_sh;
+ struct GPUShader *studiolight_background_sh;
+
/* Probes */
- struct GPUShader *probe_default_sh;
- struct GPUShader *probe_default_studiolight_sh;
- struct GPUShader *probe_background_studiolight_sh;
struct GPUShader *probe_grid_display_sh;
struct GPUShader *probe_cube_display_sh;
struct GPUShader *probe_planar_display_sh;
@@ -70,17 +70,16 @@ static struct {
struct GPUShader *taa_resolve_reproject_sh;
/* General purpose Shaders. */
- struct GPUShader *default_background;
+ struct GPUShader *lookdev_background;
struct GPUShader *update_noise_sh;
/* Shader strings */
- char *frag_shader_lib;
- char *vert_shader_str;
- char *vert_shadow_shader_str;
- char *vert_background_shader_str;
- char *vert_volume_shader_str;
- char *geom_volume_shader_str;
- char *volume_shader_lib;
+ char *closure_lit_lib;
+ char *surface_lit_frag;
+ char *surface_prepass_frag;
+ char *surface_geom_barycentric;
+
+ DRWShaderLibrary *lib;
/* LookDev Materials */
Material *glossy_mat;
@@ -88,6 +87,8 @@ static struct {
Material *error_mat;
+ World *default_world;
+
/* Default Material */
struct {
bNodeTree *ntree;
@@ -103,16 +104,39 @@ static struct {
} world;
} e_data = {NULL}; /* Engine data */
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_common_math_lib_glsl[];
+extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_background_vert_glsl[];
-extern char datatoc_common_hair_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_bsdf_lut_frag_glsl[];
+extern char datatoc_bsdf_sampling_lib_glsl[];
+extern char datatoc_btdf_lut_frag_glsl[];
+extern char datatoc_closure_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_common_utiltex_lib_glsl[];
extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_default_world_frag_glsl[];
+extern char datatoc_default_frag_glsl[];
+extern char datatoc_lookdev_world_frag_glsl[];
+extern char datatoc_effect_bloom_frag_glsl[];
+extern char datatoc_effect_dof_frag_glsl[];
+extern char datatoc_effect_dof_vert_glsl[];
+extern char datatoc_effect_downsample_cube_frag_glsl[];
+extern char datatoc_effect_downsample_frag_glsl[];
+extern char datatoc_effect_gtao_frag_glsl[];
+extern char datatoc_effect_minmaxz_frag_glsl[];
+extern char datatoc_effect_mist_frag_glsl[];
+extern char datatoc_effect_motion_blur_frag_glsl[];
+extern char datatoc_effect_ssr_frag_glsl[];
+extern char datatoc_effect_subsurface_frag_glsl[];
+extern char datatoc_effect_temporal_aa_glsl[];
+extern char datatoc_effect_translucency_frag_glsl[];
+extern char datatoc_effect_velocity_resolve_frag_glsl[];
+extern char datatoc_effect_velocity_tile_frag_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lightprobe_cube_display_frag_glsl[];
extern char datatoc_lightprobe_cube_display_vert_glsl[];
@@ -131,72 +155,111 @@ extern char datatoc_lightprobe_planar_downsample_geom_glsl[];
extern char datatoc_lightprobe_planar_downsample_vert_glsl[];
extern char datatoc_lightprobe_vert_glsl[];
extern char datatoc_lights_lib_glsl[];
-extern char datatoc_lit_surface_frag_glsl[];
-extern char datatoc_lit_surface_vert_glsl[];
+extern char datatoc_closure_lit_lib_glsl[];
extern char datatoc_ltc_lib_glsl[];
+extern char datatoc_object_motion_frag_glsl[];
+extern char datatoc_object_motion_vert_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_prepass_frag_glsl[];
+extern char datatoc_prepass_vert_glsl[];
extern char datatoc_raytrace_lib_glsl[];
+extern char datatoc_renderpass_lib_glsl[];
+extern char datatoc_renderpass_postprocess_frag_glsl[];
+extern char datatoc_shadow_accum_frag_glsl[];
+extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_ssr_lib_glsl[];
+extern char datatoc_surface_frag_glsl[];
+extern char datatoc_surface_geom_glsl[];
+extern char datatoc_surface_lib_glsl[];
+extern char datatoc_surface_vert_glsl[];
extern char datatoc_update_noise_frag_glsl[];
+extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
+extern char datatoc_volumetric_integration_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
+extern char datatoc_volumetric_resolve_frag_glsl[];
+extern char datatoc_volumetric_scatter_frag_glsl[];
extern char datatoc_volumetric_vert_glsl[];
-/* Velocity Resolve */
-extern char datatoc_effect_velocity_resolve_frag_glsl[];
-
-/* Temporal Sampling */
-extern char datatoc_effect_temporal_aa_glsl[];
-
/* *********** FUNCTIONS *********** */
+static void eevee_shader_library_ensure(void)
+{
+ if (e_data.lib == NULL) {
+ e_data.lib = DRW_shader_library_create();
+ /* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_uniforms_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, gpu_shader_common_obinfos_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, renderpass_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, bsdf_common_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_utiltex_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, bsdf_sampling_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, cubemap_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, raytrace_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ambient_occlusion_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, octahedron_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, irradiance_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, lightprobe_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ltc_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, lights_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, surface_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, volumetric_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, closure_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, ssr_lib);
+
+ /* Add one for each Closure */
+ e_data.closure_lit_lib = BLI_string_joinN(datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl,
+ datatoc_closure_lit_lib_glsl);
+
+ DRW_shader_library_add_file(e_data.lib, e_data.closure_lit_lib, "closure_lit_lib.glsl");
+
+ e_data.surface_lit_frag = DRW_shader_library_create_shader_string(e_data.lib,
+ datatoc_surface_frag_glsl);
+
+ e_data.surface_prepass_frag = DRW_shader_library_create_shader_string(
+ e_data.lib, datatoc_prepass_frag_glsl);
+
+ e_data.surface_geom_barycentric = DRW_shader_library_create_shader_string(
+ e_data.lib, datatoc_surface_geom_glsl);
+ }
+}
+
void EEVEE_shaders_lightprobe_shaders_init(void)
{
BLI_assert(e_data.probe_filter_glossy_sh == NULL);
- char *shader_str = NULL;
-
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_glossy_frag_glsl);
-
- e_data.probe_filter_glossy_sh = DRW_shader_create(
- datatoc_lightprobe_vert_glsl, datatoc_lightprobe_geom_glsl, shader_str, filter_defines);
-
- e_data.probe_default_sh = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- MEM_freeN(shader_str);
+ eevee_shader_library_ensure();
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_diffuse_frag_glsl);
+ e_data.probe_filter_glossy_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_lightprobe_filter_glossy_frag_glsl,
+ e_data.lib,
+ filter_defines);
- e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
+ e_data.probe_filter_diffuse_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_filter_diffuse_frag_glsl, e_data.lib, filter_defines);
- MEM_freeN(shader_str);
+ e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_filter_visibility_frag_glsl, e_data.lib, filter_defines);
- shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_lightprobe_filter_visibility_frag_glsl);
-
- e_data.probe_filter_visibility_sh = DRW_shader_create_fullscreen(shader_str, filter_defines);
-
- MEM_freeN(shader_str);
-
- e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen(datatoc_lightprobe_grid_fill_frag_glsl,
- filter_defines);
+ e_data.probe_grid_fill_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_lightprobe_grid_fill_frag_glsl, e_data.lib, filter_defines);
e_data.probe_planar_downsample_sh = DRW_shader_create(
datatoc_lightprobe_planar_downsample_vert_glsl,
@@ -207,70 +270,18 @@ void EEVEE_shaders_lightprobe_shaders_init(void)
void EEVEE_shaders_material_shaders_init(void)
{
- e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_ssr_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_ltc_lib_glsl,
- datatoc_lights_lib_glsl,
- /* Add one for each Closure */
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_lit_surface_frag_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volume_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_ambient_occlusion_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_ltc_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_volumetric_lib_glsl,
- datatoc_volumetric_frag_glsl);
-
- e_data.vert_shader_str = BLI_string_joinN(
- datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_lit_surface_vert_glsl);
-
- e_data.vert_shadow_shader_str = BLI_string_joinN(
- datatoc_common_view_lib_glsl, datatoc_common_hair_lib_glsl, datatoc_shadow_vert_glsl);
-
- e_data.vert_background_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_background_vert_glsl);
-
- e_data.vert_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_volumetric_vert_glsl);
-
- e_data.geom_volume_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_volumetric_geom_glsl);
+ eevee_shader_library_ensure();
}
-GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
+DRWShaderLibrary *EEVEE_shader_lib_get(void)
{
- return e_data.probe_filter_glossy_sh;
+ eevee_shader_library_ensure();
+ return e_data.lib;
}
-GPUShader *EEVEE_shaders_probe_default_sh_get(void)
+GPUShader *EEVEE_shaders_probe_filter_glossy_sh_get(void)
{
- return e_data.probe_default_sh;
+ return e_data.probe_filter_glossy_sh;
}
GPUShader *EEVEE_shaders_probe_filter_diffuse_sh_get(void)
@@ -293,59 +304,40 @@ GPUShader *EEVEE_shaders_probe_planar_downsample_sh_get(void)
return e_data.probe_planar_downsample_sh;
}
-GPUShader *EEVEE_shaders_default_studiolight_sh_get(void)
+GPUShader *EEVEE_shaders_studiolight_probe_sh_get(void)
{
- if (e_data.probe_default_studiolight_sh == NULL) {
- e_data.probe_default_studiolight_sh = DRW_shader_create_with_lib(
- datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- "#define LOOKDEV\n");
- }
- return e_data.probe_default_studiolight_sh;
+ if (e_data.studiolight_probe_sh == NULL) {
+ e_data.studiolight_probe_sh = DRW_shader_create_with_shaderlib(datatoc_background_vert_glsl,
+ NULL,
+ datatoc_lookdev_world_frag_glsl,
+ e_data.lib,
+ SHADER_DEFINES);
+ }
+ return e_data.studiolight_probe_sh;
}
-GPUShader *EEVEE_shaders_background_studiolight_sh_get(void)
+GPUShader *EEVEE_shaders_studiolight_background_sh_get(void)
{
- if (e_data.probe_background_studiolight_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_default_world_frag_glsl);
-
- e_data.probe_background_studiolight_sh = DRW_shader_create_with_lib(
+ if (e_data.studiolight_background_sh == NULL) {
+ e_data.studiolight_background_sh = DRW_shader_create_with_shaderlib(
datatoc_background_vert_glsl,
NULL,
- frag_str,
- datatoc_common_view_lib_glsl,
+ datatoc_lookdev_world_frag_glsl,
+ e_data.lib,
"#define LOOKDEV_BG\n" SHADER_DEFINES);
-
- MEM_freeN(frag_str);
}
- return e_data.probe_background_studiolight_sh;
+ return e_data.studiolight_background_sh;
}
GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
{
if (e_data.probe_cube_display_sh == NULL) {
- char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_lightprobe_cube_display_frag_glsl);
-
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_cube_display_vert_glsl);
-
- e_data.probe_cube_display_sh = DRW_shader_create(vert_str, NULL, shader_str, SHADER_DEFINES);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_cube_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_cube_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_cube_display_frag_glsl,
+ e_data.lib,
+ SHADER_DEFINES);
}
return e_data.probe_cube_display_sh;
}
@@ -353,22 +345,12 @@ GPUShader *EEVEE_shaders_probe_cube_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
{
if (e_data.probe_grid_display_sh == NULL) {
- char *shader_str = BLI_string_joinN(datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lightprobe_lib_glsl,
- datatoc_lightprobe_grid_display_frag_glsl);
-
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_grid_display_vert_glsl);
-
- e_data.probe_grid_display_sh = DRW_shader_create(vert_str, NULL, shader_str, filter_defines);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_grid_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_grid_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_grid_display_frag_glsl,
+ e_data.lib,
+ filter_defines);
}
return e_data.probe_grid_display_sh;
}
@@ -376,16 +358,12 @@ GPUShader *EEVEE_shaders_probe_grid_display_sh_get(void)
GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
{
if (e_data.probe_planar_display_sh == NULL) {
- char *vert_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_planar_display_vert_glsl);
-
- char *shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_lightprobe_planar_display_frag_glsl);
-
- e_data.probe_planar_display_sh = DRW_shader_create(vert_str, NULL, shader_str, NULL);
-
- MEM_freeN(vert_str);
- MEM_freeN(shader_str);
+ e_data.probe_planar_display_sh = DRW_shader_create_with_shaderlib(
+ datatoc_lightprobe_planar_display_vert_glsl,
+ NULL,
+ datatoc_lightprobe_planar_display_frag_glsl,
+ e_data.lib,
+ NULL);
}
return e_data.probe_planar_display_sh;
}
@@ -393,34 +371,17 @@ GPUShader *EEVEE_shaders_probe_planar_display_sh_get(void)
GPUShader *EEVEE_shaders_velocity_resolve_sh_get(void)
{
if (e_data.velocity_resolve_sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_velocity_resolve_frag_glsl);
-
- e_data.velocity_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL);
-
- MEM_freeN(frag_str);
+ e_data.velocity_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_velocity_resolve_frag_glsl, e_data.lib, NULL);
}
return e_data.velocity_resolve_sh;
}
-GPUShader *EEVEE_shaders_default_background_sh_get(void)
-{
- if (e_data.default_background == NULL) {
- e_data.default_background = DRW_shader_create_with_lib(datatoc_background_vert_glsl,
- NULL,
- datatoc_default_world_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- }
- return e_data.default_background;
-}
-
GPUShader *EEVEE_shaders_update_noise_sh_get(void)
{
if (e_data.update_noise_sh == NULL) {
- e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
+ e_data.update_noise_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_update_noise_frag_glsl, e_data.lib, NULL);
}
return e_data.update_noise_sh;
}
@@ -437,13 +398,8 @@ GPUShader *EEVEE_shaders_taa_resolve_sh_get(EEVEE_EffectsFlag enabled_effects)
sh = &e_data.taa_resolve_sh;
}
if (*sh == NULL) {
- char *frag_str = BLI_string_joinN(datatoc_common_uniforms_lib_glsl,
- datatoc_common_view_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_effect_temporal_aa_glsl);
-
- *sh = DRW_shader_create_fullscreen(frag_str, define);
- MEM_freeN(frag_str);
+ *sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_temporal_aa_glsl, e_data.lib, define);
}
return *sh;
@@ -583,6 +539,18 @@ struct bNodeTree *EEVEE_shader_default_world_nodetree(World *wo)
return e_data.world.ntree;
}
+World *EEVEE_world_default_get(void)
+{
+ if (e_data.default_world == NULL) {
+ e_data.default_world = BKE_id_new_nomain(ID_WO, "EEVEEE default world");
+ copy_v3_fl(&e_data.default_world->horr, 0.0f);
+ e_data.default_world->use_nodes = 0;
+ e_data.default_world->nodetree = NULL;
+ BLI_listbase_clear(&e_data.default_world->gpumaterial);
+ }
+ return e_data.default_world;
+}
+
static char *eevee_get_defines(int options)
{
char *str = NULL;
@@ -605,7 +573,7 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_HAIR) != 0) {
BLI_dynstr_append(ds, "#define HAIR_SHADER\n");
}
- if ((options & (VAR_MAT_PROBE | VAR_WORLD_PROBE)) != 0) {
+ if ((options & VAR_WORLD_PROBE) != 0) {
BLI_dynstr_append(ds, "#define PROBE_CAPTURE\n");
}
if ((options & VAR_MAT_HASH) != 0) {
@@ -635,13 +603,13 @@ static char *eevee_get_vert(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.vert_volume_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_vert_glsl);
}
else if ((options & (VAR_WORLD_PROBE | VAR_WORLD_BACKGROUND)) != 0) {
- str = BLI_strdup(e_data.vert_background_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_background_vert_glsl);
}
else {
- str = BLI_strdup(e_data.vert_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_surface_vert_glsl);
}
return str;
@@ -652,7 +620,7 @@ static char *eevee_get_geom(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.geom_volume_shader_str);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_geom_glsl);
}
return str;
@@ -663,18 +631,36 @@ static char *eevee_get_frag(int options)
char *str = NULL;
if ((options & VAR_MAT_VOLUME) != 0) {
- str = BLI_strdup(e_data.volume_shader_lib);
+ str = DRW_shader_library_create_shader_string(e_data.lib, datatoc_volumetric_frag_glsl);
}
else if ((options & VAR_MAT_DEPTH) != 0) {
- str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_prepass_frag_glsl);
+ str = BLI_strdup(e_data.surface_prepass_frag);
}
else {
- str = BLI_strdup(e_data.frag_shader_lib);
+ str = BLI_strdup(e_data.surface_lit_frag);
}
return str;
}
+static void eevee_material_post_eval(GPUMaterial *mat,
+ int options,
+ const char **UNUSED(vert_code),
+ const char **geom_code,
+ const char **UNUSED(frag_lib),
+ const char **UNUSED(defines))
+{
+ const bool is_hair = (options & VAR_MAT_HAIR) != 0;
+ const bool is_mesh = (options & VAR_MAT_MESH) != 0;
+
+ /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used.
+ * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */
+ if (!is_hair && is_mesh && GPU_material_flag_get(mat, GPU_MATFLAG_BARYCENTRIC) &&
+ *geom_code == NULL) {
+ *geom_code = e_data.surface_geom_barycentric;
+ }
+}
+
static struct GPUMaterial *eevee_material_get_ex(
struct Scene *scene, Material *ma, World *wo, int options, bool deferred)
{
@@ -702,14 +688,16 @@ static struct GPUMaterial *eevee_material_get_ex(
char *frag = eevee_get_frag(options);
if (ma) {
+ GPUMaterialEvalCallbackFn cbfn = &eevee_material_post_eval;
+
bNodeTree *ntree = !is_default ? ma->nodetree : EEVEE_shader_default_surface_nodetree(ma);
mat = DRW_shader_create_from_material(
- scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ scene, ma, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, cbfn);
}
else {
bNodeTree *ntree = !is_default ? wo->nodetree : EEVEE_shader_default_world_nodetree(wo);
mat = DRW_shader_create_from_world(
- scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred);
+ scene, wo, ntree, engine, options, is_volume, vert, geom, frag, defines, deferred, NULL);
}
MEM_SAFE_FREE(defines);
@@ -764,30 +752,31 @@ struct GPUMaterial *EEVEE_material_get(
void EEVEE_shaders_free(void)
{
- MEM_SAFE_FREE(e_data.frag_shader_lib);
- MEM_SAFE_FREE(e_data.vert_shader_str);
- MEM_SAFE_FREE(e_data.vert_shadow_shader_str);
- MEM_SAFE_FREE(e_data.vert_background_shader_str);
- MEM_SAFE_FREE(e_data.vert_volume_shader_str);
- MEM_SAFE_FREE(e_data.geom_volume_shader_str);
- MEM_SAFE_FREE(e_data.volume_shader_lib);
- DRW_SHADER_FREE_SAFE(e_data.default_background);
+ MEM_SAFE_FREE(e_data.closure_lit_lib);
+ MEM_SAFE_FREE(e_data.surface_prepass_frag);
+ MEM_SAFE_FREE(e_data.surface_lit_frag);
+ MEM_SAFE_FREE(e_data.surface_geom_barycentric);
+ DRW_SHADER_FREE_SAFE(e_data.lookdev_background);
DRW_SHADER_FREE_SAFE(e_data.update_noise_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_default_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_glossy_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_diffuse_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_filter_visibility_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_fill_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_downsample_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_default_studiolight_sh);
- DRW_SHADER_FREE_SAFE(e_data.probe_background_studiolight_sh);
+ DRW_SHADER_FREE_SAFE(e_data.studiolight_probe_sh);
+ DRW_SHADER_FREE_SAFE(e_data.studiolight_background_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_grid_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_cube_display_sh);
DRW_SHADER_FREE_SAFE(e_data.probe_planar_display_sh);
DRW_SHADER_FREE_SAFE(e_data.velocity_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
+ DRW_SHADER_LIB_FREE_SAFE(e_data.lib);
+ if (e_data.default_world) {
+ BKE_id_free(NULL, e_data.default_world);
+ e_data.default_world = NULL;
+ }
if (e_data.glossy_mat) {
BKE_id_free(NULL, e_data.glossy_mat);
e_data.glossy_mat = NULL;
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index 8c50b26b45f..71a4da9fcab 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -42,11 +42,6 @@ static struct {
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
extern char datatoc_shadow_accum_frag_glsl[];
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@@ -65,23 +60,13 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (!e_data.shadow_sh) {
- e_data.shadow_sh = DRW_shader_create_with_lib(datatoc_shadow_vert_glsl,
- NULL,
- datatoc_shadow_frag_glsl,
- datatoc_common_view_lib_glsl,
- NULL);
- }
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
- if (!e_data.shadow_accum_sh) {
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_shadow_accum_frag_glsl);
+ e_data.shadow_sh = DRW_shader_create_with_shaderlib(
+ datatoc_shadow_vert_glsl, NULL, datatoc_shadow_frag_glsl, lib, NULL);
- e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
- MEM_freeN(frag_str);
+ e_data.shadow_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_shadow_accum_frag_glsl, lib, SHADER_DEFINES);
}
if (!sldata->lights) {
@@ -400,7 +385,7 @@ void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_EffectsInfo *effects = stl->effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
const eGPUTextureFormat texture_format = GPU_R32F;
diff --git a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
index 1fd8d818b33..246bc18b71a 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows_cascade.c
@@ -139,7 +139,7 @@ static void eevee_shadow_cascade_setup(EEVEE_LightsInfo *linfo,
float jitter_ofs[2];
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
- uint ht_primes[2] = {2, 3};
+ const uint ht_primes[2] = {2, 3};
BLI_halton_2d(ht_primes, ht_offset, sample_ofs, ht_point);
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index ef4588f4aca..74fb7ac99b7 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -38,41 +38,19 @@ static struct {
struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
-extern char datatoc_common_view_lib_glsl[];
-extern char datatoc_common_uniforms_lib_glsl[];
-extern char datatoc_lights_lib_glsl[];
-extern char datatoc_raytrace_lib_glsl[];
-extern char datatoc_octahedron_lib_glsl[];
-extern char datatoc_cubemap_lib_glsl[];
-extern char datatoc_bsdf_sampling_lib_glsl[];
-extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_effect_subsurface_frag_glsl[];
extern char datatoc_effect_translucency_frag_glsl[];
static void eevee_create_shader_subsurface(void)
{
- char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_effect_subsurface_frag_glsl);
-
- /* TODO(fclem) remove some of these dependencies. */
- char *frag_translucent_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_bsdf_sampling_lib_glsl,
- datatoc_raytrace_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_effect_translucency_frag_glsl);
-
- e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
- e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
- e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
- "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
-
- MEM_freeN(frag_translucent_str);
- MEM_freeN(frag_str);
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.sss_sh[0] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_subsurface_frag_glsl, lib, "#define FIRST_PASS\n");
+ e_data.sss_sh[1] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_subsurface_frag_glsl, lib, "#define SECOND_PASS\n");
+ e_data.sss_sh[2] = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_effect_translucency_frag_glsl, lib, "#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
}
void EEVEE_subsurface_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *UNUSED(vedata))
@@ -188,7 +166,7 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
* pass in look dev mode active. `texture_created` will make sure that newly created textures
* are cleared. */
if (effects->taa_current_sample == 1 || texture_created) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(fbl->sss_accum_fb);
GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
}
@@ -304,7 +282,7 @@ void EEVEE_subsurface_data_render(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
EEVEE_EffectsInfo *effects = stl->effects;
if ((effects->enabled_effects & EFFECT_SSS) != 0) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Clear sss_data texture only... can this be done in a more clever way? */
GPU_framebuffer_bind(fbl->sss_clear_fb);
GPU_framebuffer_clear_color(fbl->sss_clear_fb, clear);
@@ -342,7 +320,7 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_EffectsInfo *effects = stl->effects;
if ((effects->enabled_effects & EFFECT_SSS) != 0) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
DRW_stats_group_start("SSS");
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index e184a80d2f6..12b50030435 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -171,7 +171,7 @@ void EEVEE_temporal_sampling_update_matrices(EEVEE_Data *vedata)
double ht_point[2];
double ht_offset[2] = {0.0, 0.0};
- uint ht_primes[2] = {2, 3};
+ const uint ht_primes[2] = {2, 3};
BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 300022e97a9..e1e65c29b4f 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -44,16 +44,12 @@
#include "DEG_depsgraph_query.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "eevee_private.h"
static struct {
- char *volumetric_common_lib;
- char *volumetric_common_lights_lib;
-
struct GPUShader *volumetric_clear_sh;
struct GPUShader *scatter_sh;
struct GPUShader *scatter_with_lights_sh;
@@ -97,57 +93,48 @@ extern char datatoc_common_fullscreen_vert_glsl[];
static void eevee_create_shader_volumes(void)
{
- e_data.volumetric_common_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volumetric_common_lights_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
- datatoc_common_uniforms_lib_glsl,
- datatoc_bsdf_common_lib_glsl,
- datatoc_octahedron_lib_glsl,
- datatoc_cubemap_lib_glsl,
- datatoc_irradiance_lib_glsl,
- datatoc_lights_lib_glsl,
- datatoc_volumetric_lib_glsl);
-
- e_data.volumetric_clear_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_frag_glsl,
- e_data.volumetric_common_lib,
- "#define VOLUMETRICS\n"
- "#define CLEAR\n");
- e_data.scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_SHADOW\n");
- e_data.scatter_with_lights_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_LIGHTING\n"
- "#define VOLUME_SHADOW\n");
- e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
+ DRWShaderLibrary *lib = EEVEE_shader_lib_get();
+
+ e_data.volumetric_clear_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define CLEAR\n");
+
+ e_data.scatter_sh = DRW_shader_create_with_shaderlib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_SHADOW\n");
+
+ e_data.scatter_with_lights_sh = DRW_shader_create_with_shaderlib(
+ datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_LIGHTING\n"
+ "#define VOLUME_SHADOW\n");
+
+ e_data.volumetric_integration_sh = DRW_shader_create_with_shaderlib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
datatoc_volumetric_integration_frag_glsl,
- e_data.volumetric_common_lib,
+ lib,
USE_VOLUME_OPTI ? "#extension GL_ARB_shader_image_load_store: enable\n"
"#extension GL_ARB_shading_language_420pack: enable\n"
- "#define USE_VOLUME_OPTI\n" :
- NULL);
- e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(datatoc_common_fullscreen_vert_glsl,
- NULL,
- datatoc_volumetric_resolve_frag_glsl,
- e_data.volumetric_common_lib,
- NULL);
- e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
- NULL);
+ "#define USE_VOLUME_OPTI\n" SHADER_DEFINES :
+ SHADER_DEFINES);
+
+ e_data.volumetric_resolve_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_volumetric_resolve_frag_glsl, lib, SHADER_DEFINES);
+ e_data.volumetric_accum_sh = DRW_shader_create_fullscreen_with_shaderlib(
+ datatoc_volumetric_accum_frag_glsl, lib, SHADER_DEFINES);
const float density[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, density);
@@ -162,7 +149,7 @@ void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample)
double ht_point[3];
double ht_offset[3] = {0.0, 0.0};
- uint ht_primes[3] = {3, 7, 2};
+ const uint ht_primes[3] = {3, 7, 2};
BLI_halton_3d(ht_primes, ht_offset, current_sample, ht_point);
@@ -259,17 +246,11 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_shadow_steps = 0;
}
- /* Update view_vecs */
- float invproj[4][4], winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
- DRW_view_winmat_get(NULL, invproj, true);
- EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
-
if (DRW_view_is_persp_get(NULL)) {
float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f));
- const float clip_start = common_data->view_vecs[0][2];
+ const float clip_start = DRW_view_near_distance_get(NULL);
/* Negate */
float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
float far = integration_end = min_ff(-integration_end, near - 1e-4f);
@@ -280,8 +261,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_depth_param[2] = sample_distribution;
}
else {
- const float clip_start = common_data->view_vecs[0][2];
- const float clip_end = clip_start + common_data->view_vecs[1][2];
+ const float clip_start = DRW_view_near_distance_get(NULL);
+ const float clip_end = DRW_view_far_distance_get(NULL);
integration_start = min_ff(integration_end, clip_start);
integration_end = max_ff(-integration_end, clip_end);
@@ -298,8 +279,8 @@ void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
if (!e_data.dummy_scatter) {
- float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_scatter = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, scatter);
e_data.dummy_transmit = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, transmit);
}
@@ -504,12 +485,7 @@ static bool eevee_volume_object_mesh_init(Scene *scene,
#endif
if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS) /* && show_smoke */) {
- if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) {
- GPU_create_smoke(fmd, 0);
- }
- else if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- GPU_create_smoke(fmd, 1);
- }
+ DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(fmd));
}
@@ -841,16 +817,13 @@ void EEVEE_volumes_free_smoke_textures(void)
/* Free Smoke Textures after rendering */
LISTBASE_FOREACH (LinkData *, link, &e_data.smoke_domains) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke(fmd);
+ DRW_smoke_free(fmd);
}
BLI_freelistN(&e_data.smoke_domains);
}
void EEVEE_volumes_free(void)
{
- MEM_SAFE_FREE(e_data.volumetric_common_lib);
- MEM_SAFE_FREE(e_data.volumetric_common_lights_lib);
-
DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter);
DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit);
@@ -879,7 +852,7 @@ void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
EEVEE_PassList *psl = vedata->psl;
EEVEE_EffectsInfo *effects = stl->effects;
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Create FrameBuffer. */
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index 57b16418696..2f6f8327f58 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+
/* Based on Practical Realtime Strategies for Accurate Indirect Occlusion
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pdf
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx
@@ -24,12 +27,6 @@
#define MAX_SEARCH_ITER 32
#define MAX_LOD 6.0
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
uniform sampler2D horizonBuffer;
/* aoSettings flags */
@@ -243,6 +240,11 @@ float gtao_multibounce(float visibility, vec3 albedo)
return max(x, ((x * a + b) * x + c) * x);
}
+float specular_occlusion(float NV, float AO, float roughness)
+{
+ return saturate(pow(NV + AO, roughness) - 1.0 + AO);
+}
+
/* Use the right occlusion */
float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec4 rand, out vec3 bent_normal)
{
diff --git a/source/blender/draw/engines/eevee/shaders/background_vert.glsl b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
index aff8e0857f6..ab5d9a7ebe4 100644
--- a/source/blender/draw/engines/eevee/shaders/background_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/background_vert.glsl
@@ -1,17 +1,17 @@
-in vec2 pos;
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
-out vec3 viewPosition;
+in vec2 pos;
-#ifndef VOLUMETRICS
-/* necessary for compilation*/
-out vec3 worldPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
+RESOURCE_ID_VARYING
void main()
{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ PASS_RESOURCE_ID
+
gl_Position = vec4(pos, 1.0, 1.0);
viewPosition = vec3(pos, -1.0);
@@ -22,6 +22,6 @@ void main()
#endif
#ifdef USE_ATTR
- pass_attr(viewPosition);
+ pass_attr(viewPosition, NormalMatrix, ModelMatrixInverse);
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index a8b8566edec..deedde64194 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -1,487 +1,7 @@
-#define M_PI 3.14159265358979323846 /* pi */
-#define M_2PI 6.28318530717958647692 /* 2*pi */
-#define M_PI_2 1.57079632679489661923 /* pi/2 */
-#define M_1_PI 0.318309886183790671538 /* 1/pi */
-#define M_1_2PI 0.159154943091895335768 /* 1/(2*pi) */
-#define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */
-#define FLT_MAX 3.402823e+38
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
-#define LUT_SIZE 64
-
-/* Buffers */
-uniform sampler2D colorBuffer;
-uniform sampler2D depthBuffer;
-uniform sampler2D maxzBuffer;
-uniform sampler2D minzBuffer;
-uniform sampler2DArray planarDepth;
-
-#define cameraForward ViewMatrixInverse[2].xyz
-#define cameraPos ViewMatrixInverse[3].xyz
-#define cameraVec \
- ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
-#define viewCameraVec \
- ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
-
-/* ------- Structures -------- */
-
-/* ------ Lights ----- */
-struct LightData {
- vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
- vec4 color_spec; /* w : Spec Intensity */
- vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
- vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
- vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
- vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
-};
-
-/* convenience aliases */
-#define l_color color_spec.rgb
-#define l_spec color_spec.a
-#define l_position position_influence.xyz
-#define l_influence position_influence.w
-#define l_sizex rightvec_sizex.w
-#define l_sizey upvec_sizey.w
-#define l_right rightvec_sizex.xyz
-#define l_up upvec_sizey.xyz
-#define l_forward forwardvec_type.xyz
-#define l_type forwardvec_type.w
-#define l_spot_size spotdata_radius_shadow.x
-#define l_spot_blend spotdata_radius_shadow.y
-#define l_radius spotdata_radius_shadow.z
-#define l_shadowid spotdata_radius_shadow.w
-
-/* ------ Shadows ----- */
-#ifndef MAX_CASCADE_NUM
-# define MAX_CASCADE_NUM 4
-#endif
-
-struct ShadowData {
- vec4 near_far_bias_id;
- vec4 contact_shadow_data;
-};
-
-struct ShadowCubeData {
- mat4 shadowmat;
- vec4 position;
-};
-
-struct ShadowCascadeData {
- mat4 shadowmat[MAX_CASCADE_NUM];
- vec4 split_start_distances;
- vec4 split_end_distances;
- vec4 shadow_vec_id;
-};
-
-/* convenience aliases */
-#define sh_near near_far_bias_id.x
-#define sh_far near_far_bias_id.y
-#define sh_bias near_far_bias_id.z
-#define sh_data_index near_far_bias_id.w
-#define sh_contact_dist contact_shadow_data.x
-#define sh_contact_offset contact_shadow_data.y
-#define sh_contact_spread contact_shadow_data.z
-#define sh_contact_thickness contact_shadow_data.w
-#define sh_shadow_vec shadow_vec_id.xyz
-#define sh_tex_index shadow_vec_id.w
-
-/* ------ Render Passes ----- */
-layout(std140) uniform renderpass_block
-{
- bool renderPassDiffuse;
- bool renderPassDiffuseLight;
- bool renderPassGlossy;
- bool renderPassGlossyLight;
- bool renderPassEmit;
- bool renderPassSSSColor;
- bool renderPassEnvironment;
-};
-
-vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
-{
- return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
-}
-
-vec3 render_pass_sss_mask(vec3 sss_color)
-{
- return renderPassSSSColor ? sss_color : vec3(0.0);
-}
-
-vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
-{
- return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
-}
-
-vec3 render_pass_emission_mask(vec3 emission_light)
-{
- return renderPassEmit ? emission_light : vec3(0.0);
-}
-
-/* ------- Convenience functions --------- */
-
-vec3 mul(mat3 m, vec3 v)
-{
- return m * v;
-}
-mat3 mul(mat3 m1, mat3 m2)
-{
- return m1 * m2;
-}
-vec3 transform_direction(mat4 m, vec3 v)
-{
- return mat3(m) * v;
-}
-vec3 transform_point(mat4 m, vec3 v)
-{
- return (m * vec4(v, 1.0)).xyz;
-}
-vec3 project_point(mat4 m, vec3 v)
-{
- vec4 tmp = m * vec4(v, 1.0);
- return tmp.xyz / tmp.w;
-}
-
-#define min3(a, b, c) min(a, min(b, c))
-#define min4(a, b, c, d) min(a, min3(b, c, d))
-#define min5(a, b, c, d, e) min(a, min4(b, c, d, e))
-#define min6(a, b, c, d, e, f) min(a, min5(b, c, d, e, f))
-#define min7(a, b, c, d, e, f, g) min(a, min6(b, c, d, e, f, g))
-#define min8(a, b, c, d, e, f, g, h) min(a, min7(b, c, d, e, f, g, h))
-#define min9(a, b, c, d, e, f, g, h, i) min(a, min8(b, c, d, e, f, g, h, i))
-
-#define max3(a, b, c) max(a, max(b, c))
-#define max4(a, b, c, d) max(a, max3(b, c, d))
-#define max5(a, b, c, d, e) max(a, max4(b, c, d, e))
-#define max6(a, b, c, d, e, f) max(a, max5(b, c, d, e, f))
-#define max7(a, b, c, d, e, f, g) max(a, max6(b, c, d, e, f, g))
-#define max8(a, b, c, d, e, f, g, h) max(a, max7(b, c, d, e, f, g, h))
-#define max9(a, b, c, d, e, f, g, h, i) max(a, max8(b, c, d, e, f, g, h, i))
-
-#define avg3(a, b, c) (a + b + c) * (1.0 / 3.0)
-#define avg4(a, b, c, d) (a + b + c + d) * (1.0 / 4.0)
-#define avg5(a, b, c, d, e) (a + b + c + d + e) * (1.0 / 5.0)
-#define avg6(a, b, c, d, e, f) (a + b + c + d + e + f) * (1.0 / 6.0)
-#define avg7(a, b, c, d, e, f, g) (a + b + c + d + e + f + g) * (1.0 / 7.0)
-#define avg8(a, b, c, d, e, f, g, h) (a + b + c + d + e + f + g + h) * (1.0 / 8.0)
-#define avg9(a, b, c, d, e, f, g, h, i) (a + b + c + d + e + f + g + h + i) * (1.0 / 9.0)
-
-float min_v2(vec2 v)
-{
- return min(v.x, v.y);
-}
-float min_v3(vec3 v)
-{
- return min(v.x, min(v.y, v.z));
-}
-float min_v4(vec4 v)
-{
- return min(min(v.x, v.y), min(v.z, v.w));
-}
-float max_v2(vec2 v)
-{
- return max(v.x, v.y);
-}
-float max_v3(vec3 v)
-{
- return max(v.x, max(v.y, v.z));
-}
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
-float sum(vec2 v)
-{
- return dot(vec2(1.0), v);
-}
-float sum(vec3 v)
-{
- return dot(vec3(1.0), v);
-}
-float sum(vec4 v)
-{
- return dot(vec4(1.0), v);
-}
-
-float avg(vec2 v)
-{
- return dot(vec2(1.0 / 2.0), v);
-}
-float avg(vec3 v)
-{
- return dot(vec3(1.0 / 3.0), v);
-}
-float avg(vec4 v)
-{
- return dot(vec4(1.0 / 4.0), v);
-}
-
-float saturate(float a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec2 saturate(vec2 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec3 saturate(vec3 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-vec4 saturate(vec4 a)
-{
- return clamp(a, 0.0, 1.0);
-}
-
-float distance_squared(vec2 a, vec2 b)
-{
- a -= b;
- return dot(a, a);
-}
-float distance_squared(vec3 a, vec3 b)
-{
- a -= b;
- return dot(a, a);
-}
-float len_squared(vec3 a)
-{
- return dot(a, a);
-}
-
-float inverse_distance(vec3 V)
-{
- return max(1 / length(V), 1e-8);
-}
-
-vec2 mip_ratio_interp(float mip)
-{
- float low_mip = floor(mip);
- return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
-}
-
-/* ------- RNG ------- */
-
-float wang_hash_noise(uint s)
-{
- s = (s ^ 61u) ^ (s >> 16u);
- s *= 9u;
- s = s ^ (s >> 4u);
- s *= 0x27d4eb2du;
- s = s ^ (s >> 15u);
-
- return fract(float(s) / 4294967296.0);
-}
-
-/* ------- Fast Math ------- */
-
-/* [Drobot2014a] Low Level Optimizations for GCN */
-float fast_sqrt(float v)
-{
- return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
-}
-
-vec2 fast_sqrt(vec2 v)
-{
- return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
-}
-
-/* [Eberly2014] GPGPU Programming for Games and Science */
-float fast_acos(float v)
-{
- float res = -0.156583 * abs(v) + M_PI_2;
- res *= fast_sqrt(1.0 - abs(v));
- return (v >= 0) ? res : M_PI - res;
-}
-
-vec2 fast_acos(vec2 v)
-{
- vec2 res = -0.156583 * abs(v) + M_PI_2;
- res *= fast_sqrt(1.0 - abs(v));
- v.x = (v.x >= 0) ? res.x : M_PI - res.x;
- v.y = (v.y >= 0) ? res.y : M_PI - res.y;
- return v;
-}
-
-float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
-{
- return dot(planenormal, planeorigin - lineorigin);
-}
-
-float line_plane_intersect_dist(vec3 lineorigin,
- vec3 linedirection,
- vec3 planeorigin,
- vec3 planenormal)
-{
- return dot(planenormal, planeorigin - lineorigin) / dot(planenormal, linedirection);
-}
-
-float line_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec4 plane)
-{
- vec3 plane_co = plane.xyz * (-plane.w / len_squared(plane.xyz));
- vec3 h = lineorigin - plane_co;
- return -dot(plane.xyz, h) / dot(plane.xyz, linedirection);
-}
-
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin, vec3 planenormal)
-{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, planeorigin, planenormal);
- return lineorigin + linedirection * dist;
-}
-
-vec3 line_plane_intersect(vec3 lineorigin, vec3 linedirection, vec4 plane)
-{
- float dist = line_plane_intersect_dist(lineorigin, linedirection, plane);
- return lineorigin + linedirection * dist;
-}
-
-float line_aligned_plane_intersect_dist(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
-{
- /* aligned plane normal */
- vec3 L = planeorigin - lineorigin;
- float diskdist = length(L);
- vec3 planenormal = -normalize(L);
- return -diskdist / dot(planenormal, linedirection);
-}
-
-vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 planeorigin)
-{
- float dist = line_aligned_plane_intersect_dist(lineorigin, linedirection, planeorigin);
- if (dist < 0) {
- /* if intersection is behind we fake the intersection to be
- * really far and (hopefully) not inside the radius of interest */
- dist = 1e16;
- }
- return lineorigin + linedirection * dist;
-}
-
-float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
-{
- float a = dot(linedirection, linedirection);
- float b = dot(linedirection, lineorigin);
- float c = dot(lineorigin, lineorigin) - 1;
-
- float dist = 1e15;
- float determinant = b * b - a * c;
- if (determinant >= 0) {
- dist = (sqrt(determinant) - b) / a;
- }
-
- return dist;
-}
-
-float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
-{
- /* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
- */
- vec3 firstplane = (vec3(1.0) - lineorigin) / linedirection;
- vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
- vec3 furthestplane = max(firstplane, secondplane);
-
- return min_v3(furthestplane);
-}
-
-/* Return texture coordinates to sample Surface LUT */
-vec2 lut_coords(float cosTheta, float roughness)
-{
- float theta = acos(cosTheta);
- vec2 coords = vec2(roughness, theta / M_PI_2);
-
- /* scale and bias coordinates, for correct filtered lookup */
- return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
-}
-
-vec2 lut_coords_ltc(float cosTheta, float roughness)
-{
- vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
-
- /* scale and bias coordinates, for correct filtered lookup */
- return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
-}
-
-/* -- Tangent Space conversion -- */
-vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return T * vector.x + B * vector.y + N * vector.z;
-}
-
-vec3 world_to_tangent(vec3 vector, vec3 N, vec3 T, vec3 B)
-{
- return vec3(dot(T, vector), dot(B, vector), dot(N, vector));
-}
-
-void make_orthonormal_basis(vec3 N, out vec3 T, out vec3 B)
-{
- vec3 UpVector = abs(N.z) < 0.99999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
- T = normalize(cross(UpVector, N));
- B = cross(N, T);
-}
-
-/* ---- Opengl Depth conversion ---- */
-
-float linear_depth(bool is_persp, float z, float zf, float zn)
-{
- if (is_persp) {
- return (zn * zf) / (z * (zn - zf) + zf);
- }
- else {
- return (z * 2.0 - 1.0) * zf;
- }
-}
-
-float buffer_depth(bool is_persp, float z, float zf, float zn)
-{
- if (is_persp) {
- return (zf * (zn - z)) / (z * (zn - zf));
- }
- else {
- return (z / (zf * 2.0)) + 0.5;
- }
-}
-
-float get_view_z_from_depth(float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = 2.0 * depth - 1.0;
- return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
- }
- else {
- return viewVecs[0].z + depth * viewVecs[1].z;
- }
-}
-
-float get_depth_from_view_z(float z)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
- return d * 0.5 + 0.5;
- }
- else {
- return (z - viewVecs[0].z) / viewVecs[1].z;
- }
-}
-
-vec2 get_uvs_from_view(vec3 view)
-{
- vec3 ndc = project_point(ProjectionMatrix, view);
- return ndc.xy * 0.5 + 0.5;
-}
-
-vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- return vec3(viewVecs[0].xy + uvcoords * viewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
- }
- else {
- return viewVecs[0].xyz + vec3(uvcoords, depth) * viewVecs[1].xyz;
- }
-}
-
-vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
-{
- return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
-}
-
-vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
+vec3 specular_dominant_dir(vec3 N, vec3 V, float roughness)
{
vec3 R = -reflect(V, N);
float smoothness = 1.0 - roughness;
@@ -489,13 +9,6 @@ vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
return normalize(mix(N, R, fac));
}
-float specular_occlusion(float NV, float AO, float roughness)
-{
- return saturate(pow(NV + AO, roughness) - 1.0 + AO);
-}
-
-/* --- Refraction utils --- */
-
float ior_from_f0(float f0)
{
float f = sqrt(f0);
@@ -508,7 +21,7 @@ float f0_from_ior(float eta)
return A * A;
}
-vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
+vec3 refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
{
/* TODO: This a bad approximation. Better approximation should fit
* the refracted vector and roughness into the best prefiltered reflection
@@ -527,128 +40,6 @@ vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float
return R;
}
-float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior)
-{
- const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
-
- vec3 coords;
- /* Try to compensate for the low resolution and interpolation error. */
- coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
- (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
- (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
- coords.y = 1.0 - saturate(NV);
- coords.xy *= lut_scale_bias_texel_size.x;
- coords.xy += lut_scale_bias_texel_size.y;
-
- const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
- const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
-
- float mip = roughness * lut_lvl_scale;
- float mip_floor = floor(mip);
-
- coords.z = lut_lvl_ofs + mip_floor + 1.0;
- float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
-
- coords.z -= 1.0;
- float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
-
- float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
-
- return btdf;
-}
-
-/* ---- Encode / Decode Normal buffer data ---- */
-/* From http://aras-p.info/texts/CompactNormalStorage.html
- * Using Method #4: Spheremap Transform */
-vec2 normal_encode(vec3 n, vec3 view)
-{
- float p = sqrt(n.z * 8.0 + 8.0);
- return n.xy / p + 0.5;
-}
-
-vec3 normal_decode(vec2 enc, vec3 view)
-{
- vec2 fenc = enc * 4.0 - 2.0;
- float f = dot(fenc, fenc);
- float g = sqrt(1.0 - f / 4.0);
- vec3 n;
- n.xy = fenc * g;
- n.z = 1 - f / 2;
- return n;
-}
-
-/* ---- RGBM (shared multiplier) encoding ---- */
-/* From http://iwasbeingirony.blogspot.fr/2010/06/difference-between-rgbm-and-rgbd.html */
-
-/* Higher RGBM_MAX_RANGE gives imprecision issues in low intensity. */
-#define RGBM_MAX_RANGE 512.0
-
-vec4 rgbm_encode(vec3 rgb)
-{
- float maxRGB = max_v3(rgb);
- float M = maxRGB / RGBM_MAX_RANGE;
- M = ceil(M * 255.0) / 255.0;
- return vec4(rgb / (M * RGBM_MAX_RANGE), M);
-}
-
-vec3 rgbm_decode(vec4 data)
-{
- return data.rgb * (data.a * RGBM_MAX_RANGE);
-}
-
-/* ---- RGBE (shared exponent) encoding ---- */
-vec4 rgbe_encode(vec3 rgb)
-{
- float maxRGB = max_v3(rgb);
- float fexp = ceil(log2(maxRGB));
- return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
-}
-
-vec3 rgbe_decode(vec4 data)
-{
- float fexp = data.a * 255.0 - 128.0;
- return data.rgb * exp2(fexp);
-}
-
-#if 1
-# define irradiance_encode rgbe_encode
-# define irradiance_decode rgbe_decode
-#else /* No ecoding (when using floating point format) */
-# define irradiance_encode(X) (X).rgbb
-# define irradiance_decode(X) (X).rgb
-#endif
-
-/* Irradiance Visibility Encoding */
-#if 1
-vec4 visibility_encode(vec2 accum, float range)
-{
- accum /= range;
-
- vec4 data;
- data.x = fract(accum.x);
- data.y = floor(accum.x) / 255.0;
- data.z = fract(accum.y);
- data.w = floor(accum.y) / 255.0;
-
- return data;
-}
-
-vec2 visibility_decode(vec4 data, float range)
-{
- return (data.xz + data.yw * 255.0) * range;
-}
-#else /* No ecoding (when using floating point format) */
-vec4 visibility_encode(vec2 accum, float range)
-{
- return accum.xyxy;
-}
-
-vec2 visibility_decode(vec4 data, float range)
-{
- return data.xy;
-}
-#endif
-
/* Fresnel monochromatic, perfect mirror */
float F_eta(float eta, float cos_theta)
{
@@ -766,265 +157,3 @@ float cone_cosine(float r)
/* Jimenez 2016 in Practical Realtime Strategies for Accurate Indirect Occlusion*/
return exp2(-3.32193 * r * r);
}
-
-/* --------- Closure ---------- */
-
-#ifdef VOLUMETRICS
-
-struct Closure {
- vec3 absorption;
- vec3 scatter;
- vec3 emission;
- float anisotropy;
-};
-
-Closure nodetree_exec(void); /* Prototype */
-
-# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), vec3(0.0), 0.0)
-
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
- cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
- cl.emission = mix(cl1.emission, cl2.emission, fac);
- cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.absorption = cl1.absorption + cl2.absorption;
- cl.scatter = cl1.scatter + cl2.scatter;
- cl.emission = cl1.emission + cl2.emission;
- cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.emission = rgb;
- return cl;
-}
-
-#else /* VOLUMETRICS */
-
-struct Closure {
- vec3 radiance;
- vec3 transmittance;
- float holdout;
-# ifdef USE_SSS
- vec3 sss_irradiance;
- vec3 sss_albedo;
- float sss_radius;
-# endif
- vec4 ssr_data;
- vec2 ssr_normal;
- int flag;
-};
-
-Closure nodetree_exec(void); /* Prototype */
-
-# define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
-
-# define CLOSURE_SSR_FLAG 1
-# define CLOSURE_SSS_FLAG 2
-# define CLOSURE_HOLDOUT_FLAG 4
-
-# ifdef USE_SSS
-# define CLOSURE_DEFAULT \
- Closure(vec3(0.0), vec3(0.0), 0.0, vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
-# else
-# define CLOSURE_DEFAULT Closure(vec3(0.0), vec3(0.0), 0.0, vec4(0.0), vec2(0.0), 0)
-# endif
-
-uniform int outputSsrId = 1;
-uniform int outputSssId = 1;
-
-void closure_load_ssr_data(
- vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
-{
- /* Still encode to avoid artifacts in the SSR pass. */
- vec3 vN = normalize(mat3(ViewMatrix) * N);
- cl.ssr_normal = normal_encode(vN, viewVec);
-
- if (ssr_id == outputSsrId) {
- cl.ssr_data = vec4(ssr_spec, roughness);
- cl.flag |= CLOSURE_SSR_FLAG;
- }
-}
-
-void closure_load_sss_data(
- float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
-{
-# ifdef USE_SSS
- if (sss_id == outputSssId) {
- cl.sss_irradiance = sss_irradiance;
- cl.sss_radius = radius;
- cl.sss_albedo = sss_albedo;
- cl.flag |= CLOSURE_SSS_FLAG;
- cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
- }
- else
-# endif
- {
- cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
- }
-}
-
-Closure closure_mix(Closure cl1, Closure cl2, float fac)
-{
- Closure cl;
- cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
-
- if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 1.0;
- }
- else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
- fac = 0.0;
- }
-
- cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
- cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_add(Closure cl1, Closure cl2)
-{
- Closure cl;
- cl.transmittance = cl1.transmittance + cl2.transmittance;
- cl.radiance = cl1.radiance + cl2.radiance;
- cl.holdout = cl1.holdout + cl2.holdout;
- cl.flag = cl1.flag | cl2.flag;
- cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
- bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
- /* When mixing SSR don't blend roughness and normals.*/
- cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
- cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
-
-# ifdef USE_SSS
- cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
- bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
- /* It also does not make sense to mix SSS radius or irradiance. */
- cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
- cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
-# endif
- return cl;
-}
-
-Closure closure_emission(vec3 rgb)
-{
- Closure cl = CLOSURE_DEFAULT;
- cl.radiance = rgb;
- return cl;
-}
-
-/* Breaking this across multiple lines causes issues for some older GLSL compilers. */
-/* clang-format off */
-# if defined(MESH_SHADER) && !defined(DEPTH_SHADER)
-/* clang-format on */
-# ifndef USE_ALPHA_BLEND
-layout(location = 0) out vec4 outRadiance;
-layout(location = 1) out vec2 ssrNormals;
-layout(location = 2) out vec4 ssrData;
-# ifdef USE_SSS
-layout(location = 3) out vec3 sssIrradiance;
-layout(location = 4) out float sssRadius;
-layout(location = 5) out vec3 sssAlbedo;
-# endif
-# else /* USE_ALPHA_BLEND */
-/* Use dual source blending to be able to make a whole range of effects. */
-layout(location = 0, index = 0) out vec4 outRadiance;
-layout(location = 0, index = 1) out vec4 outTransmittance;
-# endif /* USE_ALPHA_BLEND */
-
-# if defined(USE_ALPHA_BLEND)
-/* Prototype because this file is included before volumetric_lib.glsl */
-void volumetric_resolve(vec2 frag_uvs,
- float frag_depth,
- out vec3 transmittance,
- out vec3 scattering);
-# endif
-
-# define NODETREE_EXEC
-void main()
-{
- Closure cl = nodetree_exec();
-
- float holdout = saturate(1.0 - cl.holdout);
- float transmit = saturate(avg(cl.transmittance));
- float alpha = 1.0 - transmit;
-
-# ifdef USE_ALPHA_BLEND
- vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
- vec3 vol_transmit, vol_scatter;
- volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
-
- /* Removes part of the volume scattering that have
- * already been added to the destination pixels.
- * Since we do that using the blending pipeline we need to account for material transmittance. */
- vol_scatter -= vol_scatter * cl.transmittance;
-
- cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
- outRadiance = vec4(cl.radiance, alpha * holdout);
- outTransmittance = vec4(cl.transmittance, transmit) * holdout;
-# else
- outRadiance = vec4(cl.radiance, holdout);
- ssrNormals = cl.ssr_normal;
- ssrData = cl.ssr_data;
-# ifdef USE_SSS
- sssIrradiance = cl.sss_irradiance;
- sssRadius = cl.sss_radius;
- sssAlbedo = cl.sss_albedo;
-# endif
-# endif
-
- /* For Probe capture */
-# ifdef USE_SSS
- float fac = float(!sssToggle);
-
- /* TODO(fclem) we shouldn't need this.
- * Just disable USE_SSS when USE_REFRACTION is enabled. */
-# ifdef USE_REFRACTION
- /* SSRefraction pass is done after the SSS pass.
- * In order to not loose the diffuse light totally we
- * need to merge the SSS radiance to the main radiance. */
- fac = 1.0;
-# endif
-
- outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
-# endif
-
-# ifdef LOOKDEV
- gl_FragDepth = 0.0;
-# endif
-
-# ifndef USE_ALPHA_BLEND
- float alpha_div = 1.0 / max(1e-8, alpha);
- outRadiance.rgb *= alpha_div;
- ssrData.rgb *= alpha_div;
-# ifdef USE_SSS
- sssAlbedo.rgb *= alpha_div;
-# endif
-# endif
-}
-
-# endif /* MESH_SHADER */
-
-#endif /* VOLUMETRICS */
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
index f05b3396428..2b2da884fde 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_lut_frag.glsl
@@ -1,3 +1,4 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
out vec4 FragColor;
@@ -5,8 +6,8 @@ void main()
{
vec3 N, T, B, V;
- float NV = (1.0 - (clamp(gl_FragCoord.y / BRDF_LUT_SIZE, 1e-4, 0.9999)));
- float sqrtRoughness = clamp(gl_FragCoord.x / BRDF_LUT_SIZE, 1e-4, 0.9999);
+ float NV = (1.0 - (clamp(gl_FragCoord.y / b, 1e-4, 0.9999)));
+ float sqrtRoughness = clamp(gl_FragCoord.x / LUT_SIZE, 1e-4, 0.9999);
float a = sqrtRoughness * sqrtRoughness;
float a2 = a * a;
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
index 5f2b719095e..066ea58e2bf 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -1,6 +1,7 @@
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
uniform sampler1D texHammersley;
-uniform sampler2D texJitter;
uniform float sampleCount;
uniform float invSampleCount;
@@ -8,8 +9,7 @@ vec2 jitternoise = vec2(0.0);
#ifndef UTIL_TEX
# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+
#endif /* UTIL_TEX */
void setup_noise(void)
@@ -17,6 +17,11 @@ void setup_noise(void)
jitternoise = texelfetch_noise_tex(gl_FragCoord.xy).rg; /* Global variable */
}
+vec3 tangent_to_world(vec3 vector, vec3 N, vec3 T, vec3 B)
+{
+ return T * vector.x + B * vector.y + N * vector.z;
+}
+
#ifdef HAMMERSLEY_SIZE
vec3 hammersley_3d(float i, float invsamplenbr)
{
diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
index 1389a9763c0..d815d9d4e6b 100644
--- a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
@@ -1,3 +1,4 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
uniform float a2;
@@ -7,8 +8,8 @@ void main()
{
vec3 N, T, B, V;
- float x = gl_FragCoord.x / BRDF_LUT_SIZE;
- float y = gl_FragCoord.y / BRDF_LUT_SIZE;
+ float x = gl_FragCoord.x / LUT_SIZE;
+ float y = gl_FragCoord.y / LUT_SIZE;
/* There is little variation if ior > 1.0 so we
* maximize LUT precision for ior < 1.0 */
x = x * 1.1;
diff --git a/source/blender/draw/engines/eevee/shaders/closure_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl
new file mode 100644
index 00000000000..e572245ace9
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/closure_lib.glsl
@@ -0,0 +1,181 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(renderpass_lib.glsl)
+
+#ifndef VOLUMETRICS
+
+uniform int outputSsrId = 1;
+uniform int outputSssId = 1;
+
+#endif
+
+struct Closure {
+#ifdef VOLUMETRICS
+ vec3 absorption;
+ vec3 scatter;
+ vec3 emission;
+ float anisotropy;
+
+#else /* SURFACE */
+ vec3 radiance;
+ vec3 transmittance;
+ float holdout;
+ vec4 ssr_data;
+ vec2 ssr_normal;
+ int flag;
+# ifdef USE_SSS
+ vec3 sss_irradiance;
+ vec3 sss_albedo;
+ float sss_radius;
+# endif
+
+#endif
+};
+
+/* Prototype */
+Closure nodetree_exec(void);
+
+/* clang-format off */
+/* Avoid multiline defines. */
+#ifdef VOLUMETRICS
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), vec3(0), 0.0)
+#elif !defined(USE_SSS)
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0)
+#else
+# define CLOSURE_DEFAULT Closure(vec3(0), vec3(0), 0.0, vec4(0), vec2(0), 0, vec3(0), vec3(0), 0.0)
+#endif
+/* clang-format on */
+
+#define FLAG_TEST(flag, val) (((flag) & (val)) != 0)
+
+#define CLOSURE_SSR_FLAG 1
+#define CLOSURE_SSS_FLAG 2
+#define CLOSURE_HOLDOUT_FLAG 4
+
+#ifdef VOLUMETRICS
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.absorption = mix(cl1.absorption, cl2.absorption, fac);
+ cl.scatter = mix(cl1.scatter, cl2.scatter, fac);
+ cl.emission = mix(cl1.emission, cl2.emission, fac);
+ cl.anisotropy = mix(cl1.anisotropy, cl2.anisotropy, fac);
+ return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.absorption = cl1.absorption + cl2.absorption;
+ cl.scatter = cl1.scatter + cl2.scatter;
+ cl.emission = cl1.emission + cl2.emission;
+ cl.anisotropy = (cl1.anisotropy + cl2.anisotropy) / 2.0; /* Average phase (no multi lobe) */
+ return cl;
+}
+
+Closure closure_emission(vec3 rgb)
+{
+ Closure cl = CLOSURE_DEFAULT;
+ cl.emission = rgb;
+ return cl;
+}
+
+#else /* SURFACE */
+
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.holdout = mix(cl1.holdout, cl2.holdout, fac);
+
+ if (FLAG_TEST(cl1.flag, CLOSURE_HOLDOUT_FLAG)) {
+ fac = 1.0;
+ }
+ else if (FLAG_TEST(cl2.flag, CLOSURE_HOLDOUT_FLAG)) {
+ fac = 0.0;
+ }
+
+ cl.transmittance = mix(cl1.transmittance, cl2.transmittance, fac);
+ cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
+ cl.flag = cl1.flag | cl2.flag;
+ cl.ssr_data = mix(cl1.ssr_data, cl2.ssr_data, fac);
+ bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
+ /* When mixing SSR don't blend roughness and normals but only specular (ssr_data.xyz).*/
+ cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
+ cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
+
+# ifdef USE_SSS
+ cl.sss_albedo = mix(cl1.sss_albedo, cl2.sss_albedo, fac);
+ bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
+# endif
+ return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.transmittance = cl1.transmittance + cl2.transmittance;
+ cl.radiance = cl1.radiance + cl2.radiance;
+ cl.holdout = cl1.holdout + cl2.holdout;
+ cl.flag = cl1.flag | cl2.flag;
+ cl.ssr_data = cl1.ssr_data + cl2.ssr_data;
+ bool use_cl1_ssr = FLAG_TEST(cl1.flag, CLOSURE_SSR_FLAG);
+ /* When mixing SSR don't blend roughness and normals.*/
+ cl.ssr_data.w = (use_cl1_ssr) ? cl1.ssr_data.w : cl2.ssr_data.w;
+ cl.ssr_normal = (use_cl1_ssr) ? cl1.ssr_normal : cl2.ssr_normal;
+
+# ifdef USE_SSS
+ cl.sss_albedo = cl1.sss_albedo + cl2.sss_albedo;
+ bool use_cl1_sss = FLAG_TEST(cl1.flag, CLOSURE_SSS_FLAG);
+ /* It also does not make sense to mix SSS radius or irradiance. */
+ cl.sss_radius = (use_cl1_sss) ? cl1.sss_radius : cl2.sss_radius;
+ cl.sss_irradiance = (use_cl1_sss) ? cl1.sss_irradiance : cl2.sss_irradiance;
+# endif
+ return cl;
+}
+
+Closure closure_emission(vec3 rgb)
+{
+ Closure cl = CLOSURE_DEFAULT;
+ cl.radiance = rgb;
+ return cl;
+}
+
+#endif
+
+#ifndef VOLUMETRICS
+
+void closure_load_ssr_data(
+ vec3 ssr_spec, float roughness, vec3 N, vec3 viewVec, int ssr_id, inout Closure cl)
+{
+ /* Still encode to avoid artifacts in the SSR pass. */
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ cl.ssr_normal = normal_encode(vN, viewVec);
+
+ if (ssr_id == outputSsrId) {
+ cl.ssr_data = vec4(ssr_spec, roughness);
+ cl.flag |= CLOSURE_SSR_FLAG;
+ }
+}
+
+void closure_load_sss_data(
+ float radius, vec3 sss_irradiance, vec3 sss_albedo, int sss_id, inout Closure cl)
+{
+# ifdef USE_SSS
+ if (sss_id == outputSssId) {
+ cl.sss_irradiance = sss_irradiance;
+ cl.sss_radius = radius;
+ cl.sss_albedo = sss_albedo;
+ cl.flag |= CLOSURE_SSS_FLAG;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
+ }
+ else
+# endif
+ {
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
+ }
+}
+
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
index bc7879763c3..bf33caf9854 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/closure_lit_lib.glsl
@@ -1,32 +1,8 @@
-#ifndef LIT_SURFACE_UNIFORM
-# define LIT_SURFACE_UNIFORM
-
-uniform float refractionDepth;
-
-# ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-# endif /* UTIL_TEX */
-
-in vec3 worldPosition;
-in vec3 viewPosition;
-
-in vec3 worldNormal;
-in vec3 viewNormal;
-
-# ifdef HAIR_SHADER
-in vec3 hairTangent; /* world space */
-in float hairThickTime;
-in float hairThickness;
-in float hairTime;
-flat in int hairStrandID;
-
-uniform int hairThicknessRes = 1;
-# endif
-
-#endif /* LIT_SURFACE_UNIFORM */
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+#pragma BLENDER_REQUIRE(ssr_lib.glsl)
/**
* AUTO CONFIG
@@ -209,7 +185,7 @@ void CLOSURE_NAME(vec3 N
vec3 V = cameraVec;
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
/* ---------------------------------------------------------------- */
/* -------------------- SCENE LIGHTS LIGHTING --------------------- */
@@ -328,11 +304,11 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_GLOSSY
- vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
# endif
# ifdef CLOSURE_CLEARCOAT
- vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared);
+ vec3 C_spec_dir = specular_dominant_dir(C_N, V, C_roughnessSquared);
# endif
# ifdef CLOSURE_REFRACTION
@@ -345,7 +321,7 @@ void CLOSURE_NAME(vec3 N
line_plane_intersect(
worldPosition, refr_V, worldPosition - N * refractionDepth, N) :
worldPosition;
- vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
+ vec3 refr_dir = refraction_dominant_dir(N, refr_V, roughness, final_ior);
# endif
# ifdef CLOSURE_REFRACTION
@@ -485,7 +461,7 @@ void CLOSURE_NAME(vec3 N
# endif
# ifdef CLOSURE_REFRACTION
- float btdf = get_btdf_lut(utilTex, NV, roughness, ior);
+ float btdf = get_btdf_lut(NV, roughness, ior);
out_refr += refr_accum.rgb * btdf;
# endif
diff --git a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
index 759b4098b37..a6c9eebaff2 100644
--- a/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/common_uniforms_lib.glsl
@@ -2,7 +2,6 @@
layout(std140) uniform common_block
{
mat4 pastViewProjectionMatrix;
- vec4 viewVecs[2];
vec2 mipRatio[10]; /* To correct mip level texel misalignment */
/* Ambient Occlusion */
vec4 aoParameters[2];
@@ -70,3 +69,9 @@ layout(std140) uniform common_block
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
+
+vec2 mip_ratio_interp(float mip)
+{
+ float low_mip = floor(mip);
+ return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
+}
diff --git a/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl
new file mode 100644
index 00000000000..95a585f0d9c
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl
@@ -0,0 +1,65 @@
+
+#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
+
+/* ---------------------------------------------------------------------- */
+/** \name Utiltex
+ *
+ * Utiltex is a sampler2DArray that stores a number of useful small utilitary textures and lookup
+ * tables.
+ * \{ */
+
+uniform sampler2DArray utilTex;
+
+#define LUT_SIZE 64
+
+#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+
+/* Return texture coordinates to sample Surface LUT */
+vec2 lut_coords(float cosTheta, float roughness)
+{
+ float theta = acos(cosTheta);
+ vec2 coords = vec2(roughness, theta / M_PI_2);
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
+}
+
+vec2 lut_coords_ltc(float cosTheta, float roughness)
+{
+ vec2 coords = vec2(roughness, sqrt(1.0 - cosTheta));
+
+ /* scale and bias coordinates, for correct filtered lookup */
+ return coords * (LUT_SIZE - 1.0) / LUT_SIZE + 0.5 / LUT_SIZE;
+}
+
+float get_btdf_lut(float NV, float roughness, float ior)
+{
+ const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
+
+ vec3 coords;
+ /* Try to compensate for the low resolution and interpolation error. */
+ coords.x = (ior > 1.0) ? (0.9 + lut_scale_bias_texel_size.z) +
+ (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior) :
+ (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
+ coords.y = 1.0 - saturate(NV);
+ coords.xy *= lut_scale_bias_texel_size.x;
+ coords.xy += lut_scale_bias_texel_size.y;
+
+ const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
+ const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
+
+ float mip = roughness * lut_lvl_scale;
+ float mip_floor = floor(mip);
+
+ coords.z = lut_lvl_ofs + mip_floor + 1.0;
+ float btdf_high = textureLod(utilTex, coords, 0.0).r;
+
+ coords.z -= 1.0;
+ float btdf_low = textureLod(utilTex, coords, 0.0).r;
+
+ float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
+
+ return btdf;
+}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
deleted file mode 100644
index 1014b25033a..00000000000
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-
-uniform vec3 basecol;
-uniform float metallic;
-uniform float specular;
-uniform float roughness;
-
-Closure nodetree_exec(void)
-{
-#ifdef HAIR_SHADER
- vec3 B = normalize(cross(worldNormal, hairTangent));
- float cos_theta;
- if (hairThicknessRes == 1) {
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
- /* Random cosine normal distribution on the hair surface. */
- cos_theta = rand.x * 2.0 - 1.0;
- }
- else {
- /* Shade as a cylinder. */
- cos_theta = hairThickTime / hairThickness;
- }
- float sin_theta = sqrt(max(0.0, 1.0f - cos_theta * cos_theta));
- vec3 N = normalize(worldNormal * sin_theta + B * cos_theta);
- vec3 vN = mat3(ViewMatrix) * N;
-#else
- vec3 N = normalize(gl_FrontFacing ? worldNormal : -worldNormal);
- vec3 vN = normalize(gl_FrontFacing ? viewNormal : -viewNormal);
-#endif
-
- vec3 dielectric = vec3(0.034) * specular * 2.0;
- vec3 albedo = mix(basecol, vec3(0.0), metallic);
- vec3 f0 = mix(dielectric, basecol, metallic);
- vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
- vec3 out_diff, out_spec, ssr_spec;
- eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
-
- Closure cl = CLOSURE_DEFAULT;
- cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
- render_pass_diffuse_mask(albedo, out_diff * albedo);
- closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
-
-#ifdef LOOKDEV
- gl_FragDepth = 0.0;
-#endif
-
-#ifdef HOLDOUT
- cl = CLOSURE_DEFAULT;
- cl.holdout = 1.0;
-#endif
-
- return cl;
-}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
index d56890769a7..9c1ca17f87c 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_frag.glsl
@@ -1,4 +1,8 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D colorBuffer;
uniform sampler2D depthBuffer;
@@ -18,9 +22,6 @@ uniform vec4 bokehParams[2];
uniform vec2 nearFar; /* Near & far view depths values */
-#define M_PI 3.1415926535897932384626433832795
-#define M_2PI 6.2831853071795864769252868
-
/* -------------- Utils ------------- */
/* divide by sensor size to get the normalized size */
@@ -34,11 +35,6 @@ uniform vec2 nearFar; /* Near & far view depths values */
#define weighted_sum(a, b, c, d, e) \
(a * e.x + b * e.y + c * e.z + d * e.w) / max(1e-6, dot(e, vec4(1.0)));
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
vec4 safe_color(vec4 c)
{
/* Clamp to avoid black square artifacts if a pixel goes NaN. */
diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
index d83b410125a..6e35d4a54ae 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_dof_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform vec4 bokehParams[2];
#define bokeh_rotation bokehParams[0].x
@@ -15,8 +17,6 @@ flat out float smoothFac;
flat out ivec2 edge;
out vec2 particlecoord;
-#define M_PI 3.1415926535897932384626433832795
-
/* Scatter pass, calculate a triangle covering the CoC. */
void main()
{
diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
index eea0ce0aae2..47fe21928b3 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
@@ -1,14 +1,34 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+
/**
* This shader only compute maximum horizon angles for each directions.
* The final integration is done at the resolve stage with the shading normal.
*/
-uniform float rotationOffset;
-
out vec4 FragColor;
-#ifdef DEBUG_AO
uniform sampler2D normalBuffer;
+#ifdef LAYERED_DEPTH
+uniform sampler2DArray depthBufferLayered;
+uniform int layer;
+# define gtao_depthBuffer depthBufferLayered
+# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
+
+#else
+uniform sampler2D depthBuffer;
+# define gtao_depthBuffer depthBuffer
+# define gtao_textureLod(a, b, c) textureLod(a, b, c)
+
+#endif
+
+uniform float rotationOffset;
+
+#ifdef DEBUG_AO
void main()
{
@@ -34,18 +54,6 @@ void main()
#else
-# ifdef LAYERED_DEPTH
-uniform sampler2DArray depthBufferLayered;
-uniform int layer;
-# define gtao_depthBuffer depthBufferLayered
-# define gtao_textureLod(a, b, c) textureLod(a, vec3(b, layer), c)
-
-# else
-# define gtao_depthBuffer depthBuffer
-# define gtao_textureLod(a, b, c) textureLod(a, b, c)
-
-# endif
-
void main()
{
vec2 uvs = saturate(gl_FragCoord.xy / vec2(textureSize(gtao_depthBuffer, 0).xy));
diff --git a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
index edee55a07e0..7331f92ba6d 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_mist_frag.glsl
@@ -1,5 +1,10 @@
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
/* Convert depth to Mist factor */
uniform vec3 mistSettings;
+uniform sampler2D depthBuffer;
#define mistStart mistSettings.x
#define mistInvDistance mistSettings.y
diff --git a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
index fbf507a2e40..3501a4448c5 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_motion_blur_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
/*
* Based on:
* A Fast and Stable Feature-Aware Motion Blur Filter
@@ -15,11 +17,6 @@ uniform sampler2D tileMaxBuffer;
#define KERNEL 8
-/* TODO(fclem) deduplicate this code. */
-uniform sampler2DArray utilTex;
-#define LUT_SIZE 64
-#define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-
uniform float depthScale;
uniform ivec2 tileBufferSize;
uniform vec2 viewportSize;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
index 598cc3e5183..f8dccb7511a 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -1,4 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(ssr_lib.glsl)
+
/* Based on Stochastic Screen Space Reflections
* https://www.ea.com/frostbite/news/stochastic-screen-space-reflections */
@@ -131,7 +138,7 @@ void main()
return;
}
- vec4 rand = texelFetch(utilTex, ivec3(halfres_texel % LUT_SIZE, 2), 0);
+ vec4 rand = texelfetch_noise_tex(halfres_texel);
/* Gives *perfect* reflection for very small roughness */
if (roughness < 0.04) {
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index e9da49c9eb9..2a53a4f119f 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -1,4 +1,9 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+
/* Based on Separable SSS. by Jorge Jimenez and Diego Gutierrez */
#define MAX_SSS_SAMPLES 65
@@ -14,36 +19,16 @@ uniform sampler2D sssIrradiance;
uniform sampler2D sssRadius;
uniform sampler2D sssAlbedo;
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
layout(location = 0) out vec4 sssRadiance;
-float get_view_z_from_depth(float depth)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- float d = 2.0 * depth - 1.0;
- return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
- }
- else {
- return viewVecs[0].z + depth * viewVecs[1].z;
- }
-}
-
-#define LUT_SIZE 64
-#define M_PI_2 1.5707963267948966 /* pi/2 */
-#define M_2PI 6.2831853071795865 /* 2*pi */
-
void main(void)
{
vec2 pixel_size = 1.0 / vec2(textureSize(depthBuffer, 0).xy); /* TODO precompute */
vec2 uvs = gl_FragCoord.xy * pixel_size;
vec3 sss_irradiance = texture(sssIrradiance, uvs).rgb;
float sss_radius = texture(sssRadius, uvs).r;
- float depth_view = get_view_z_from_depth(texture(depthBuffer, uvs).r);
+ float depth = texture(depthBuffer, uvs).r;
+ float depth_view = get_view_z_from_depth(depth);
float rand = texelfetch_noise_tex(gl_FragCoord.xy).r;
#ifdef FIRST_PASS
diff --git a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
index b44645174bd..28947e971d2 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_temporal_aa.glsl
@@ -1,5 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
uniform sampler2D colorHistoryBuffer;
+
uniform mat4 prevViewProjectionMatrix;
out vec4 FragColor;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
index 6531ceb8dbe..c85eff92e37 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl
@@ -1,11 +1,16 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+
in vec4 uvcoordsvar;
out vec4 FragColor;
+uniform sampler2D depthBuffer;
uniform sampler1D sssTexProfile;
uniform sampler2D sssRadius;
-
uniform sampler2DArray sssShadowCubes;
uniform sampler2DArray sssShadowCascades;
@@ -27,12 +32,6 @@ vec3 sss_profile(float s)
return texture(sssTexProfile, saturate(s) * SSS_LUT_SCALE + SSS_LUT_BIAS).rgb;
}
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
float light_translucent_power_with_falloff(LightData ld, vec3 N, vec4 l_vector)
{
float power, falloff;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
index d927fd78d30..145939cefb2 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_resolve_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
+uniform sampler2D depthBuffer;
+
uniform mat4 prevViewProjMatrix;
uniform mat4 currViewProjMatrixInv;
uniform mat4 nextViewProjMatrix;
diff --git a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
index 0eb598521af..f52acaf6f7f 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_velocity_tile_frag.glsl
@@ -148,4 +148,4 @@ void main()
tileMaxVelocity = encode_velocity(max_motion);
}
-#endif \ No newline at end of file
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
index 64ea87001f4..2274bf8b950 100644
--- a/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/irradiance_lib.glsl
@@ -1,18 +1,71 @@
-uniform sampler2DArray irradianceGrid;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(octahedron_lib.glsl)
#define IRRADIANCE_LIB
+/* ---------------------------------------------------------------------- */
+/** \name Structure
+ * \{ */
+
#if defined(IRRADIANCE_SH_L2)
struct IrradianceData {
vec3 shcoefs[9];
};
+
#else /* defined(IRRADIANCE_HL2) */
struct IrradianceData {
vec3 cubesides[3];
};
+
#endif
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
+
+uniform sampler2DArray irradianceGrid;
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Functions
+ * \{ */
+
+vec4 irradiance_encode(vec3 rgb)
+{
+ float maxRGB = max_v3(rgb);
+ float fexp = ceil(log2(maxRGB));
+ return vec4(rgb / exp2(fexp), (fexp + 128.0) / 255.0);
+}
+
+vec3 irradiance_decode(vec4 data)
+{
+ float fexp = data.a * 255.0 - 128.0;
+ return data.rgb * exp2(fexp);
+}
+
+vec4 visibility_encode(vec2 accum, float range)
+{
+ accum /= range;
+
+ vec4 data;
+ data.x = fract(accum.x);
+ data.y = floor(accum.x) / 255.0;
+ data.z = fract(accum.y);
+ data.w = floor(accum.y) / 255.0;
+
+ return data;
+}
+
+vec2 visibility_decode(vec4 data, float range)
+{
+ return (data.xz + data.yw * 255.0) * range;
+}
+
IrradianceData load_irradiance_cell(int cell, vec3 N)
{
/* Keep in sync with diffuse_filter_probe() */
@@ -155,3 +208,5 @@ vec3 irradiance_from_cell_get(int cell, vec3 ir_dir)
IrradianceData ir_data = load_irradiance_cell(cell, ir_dir);
return compute_irradiance(ir_dir, ir_data);
}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
index 96fe94fc41e..b0da4274a13 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_frag.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+
flat in int pid;
in vec2 quadCoord;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
index db780714091..d06ad553ca4 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_cube_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
/* XXX TODO fix code duplication */
struct CubeData {
vec4 position_type;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
index b485511318b..bf45169ebaa 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
uniform samplerCube probeHdr;
uniform int probeSize;
uniform float lodFactor;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
index 00eb3c7e200..ccb77427ed2 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_glossy_frag.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+
uniform samplerCube probeHdr;
uniform float roughnessSquared;
uniform float texelSize;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
index 5d8af21032a..8d7c58a93d5 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_visibility_frag.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
uniform samplerCube probeDepth;
uniform int outputSize;
uniform float lodFactor;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
index f8bc1703c66..009ccf6535e 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
@@ -40,9 +40,6 @@ void main()
for (int v = 0; v < 3; v++) {
gl_Position = vPos[v];
worldPosition = x_axis[fFace] * vPos[v].x + y_axis[fFace] * vPos[v].y + maj_axes[fFace];
-#ifdef USE_ATTR
- pass_attr(v);
-#endif
EmitVertex();
}
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
index f9bcc718a1e..dc5ec1e40f5 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_frag.glsl
@@ -1,3 +1,5 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
flat in int cellOffset;
in vec2 quadCoord;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
index 4e500db827e..6fefe1319bd 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_grid_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
uniform float sphere_size;
uniform int offset;
uniform ivec3 grid_resolution;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index 6c6db88139b..a2e25b83532 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -1,3 +1,12 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(cubemap_lib.glsl)
+#pragma BLENDER_REQUIRE(ambient_occlusion_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
/* ----------- Uniforms --------- */
uniform sampler2DArray probePlanars;
@@ -73,12 +82,6 @@ struct GridData {
# define MAX_PLANAR 1
#endif
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
layout(std140) uniform probe_block
{
CubeData probes_data[MAX_PROBE];
@@ -218,7 +221,7 @@ void fallback_cubemap(vec3 N,
inout vec4 spec_accum)
{
/* Specular probes */
- vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = specular_dominant_dir(N, V, roughnessSquared);
#ifdef SSR_AO
vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
@@ -246,7 +249,6 @@ void fallback_cubemap(vec3 N,
}
}
-#ifdef IRRADIANCE_LIB
vec3 probe_evaluate_grid(GridData gd, vec3 W, vec3 N, vec3 localpos)
{
localpos = localpos * 0.5 + 0.5;
@@ -308,5 +310,3 @@ vec3 probe_evaluate_world_diff(vec3 N)
{
return irradiance_from_cell_get(0, N);
}
-
-#endif /* IRRADIANCE_LIB */
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
index 2807488db6c..0a53abcb04a 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
uniform sampler2DArray probePlanars;
in vec3 worldPosition;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
index 65506e5c7b1..6759c060259 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_display_vert.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
in vec3 pos;
in int probe_id;
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 3b9d0a8f2bc..949e4d8f04f 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -1,8 +1,76 @@
-uniform sampler2DArrayShadow shadowCubeTexture;
-uniform sampler2DArrayShadow shadowCascadeTexture;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(ltc_lib.glsl)
+
+#ifndef MAX_CASCADE_NUM
+# define MAX_CASCADE_NUM 4
+#endif
+
+/* ---------------------------------------------------------------------- */
+/** \name Structure
+ * \{ */
+
+struct LightData {
+ vec4 position_influence; /* w : InfluenceRadius (inversed and squared) */
+ vec4 color_spec; /* w : Spec Intensity */
+ vec4 spotdata_radius_shadow; /* x : spot size, y : spot blend, z : radius, w: shadow id */
+ vec4 rightvec_sizex; /* xyz: Normalized up vector, w: area size X or spot scale X */
+ vec4 upvec_sizey; /* xyz: Normalized right vector, w: area size Y or spot scale Y */
+ vec4 forwardvec_type; /* xyz: Normalized forward vector, w: Light Type */
+};
+
+/* convenience aliases */
+#define l_color color_spec.rgb
+#define l_spec color_spec.a
+#define l_position position_influence.xyz
+#define l_influence position_influence.w
+#define l_sizex rightvec_sizex.w
+#define l_sizey upvec_sizey.w
+#define l_right rightvec_sizex.xyz
+#define l_up upvec_sizey.xyz
+#define l_forward forwardvec_type.xyz
+#define l_type forwardvec_type.w
+#define l_spot_size spotdata_radius_shadow.x
+#define l_spot_blend spotdata_radius_shadow.y
+#define l_radius spotdata_radius_shadow.z
+#define l_shadowid spotdata_radius_shadow.w
+
+struct ShadowData {
+ vec4 near_far_bias_id;
+ vec4 contact_shadow_data;
+};
+
+struct ShadowCubeData {
+ mat4 shadowmat;
+ vec4 position;
+};
+
+struct ShadowCascadeData {
+ mat4 shadowmat[MAX_CASCADE_NUM];
+ vec4 split_start_distances;
+ vec4 split_end_distances;
+ vec4 shadow_vec_id;
+};
+
+/* convenience aliases */
+#define sh_near near_far_bias_id.x
+#define sh_far near_far_bias_id.y
+#define sh_bias near_far_bias_id.z
+#define sh_data_index near_far_bias_id.w
+#define sh_contact_dist contact_shadow_data.x
+#define sh_contact_offset contact_shadow_data.y
+#define sh_contact_spread contact_shadow_data.z
+#define sh_contact_thickness contact_shadow_data.w
+#define sh_shadow_vec shadow_vec_id.xyz
+#define sh_tex_index shadow_vec_id.w
+
+/** \} */
-#define LAMPS_LIB
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
layout(std140) uniform shadow_block
{
@@ -16,6 +84,15 @@ layout(std140) uniform light_block
LightData lights_data[MAX_LIGHT];
};
+uniform sampler2DArrayShadow shadowCubeTexture;
+uniform sampler2DArrayShadow shadowCascadeTexture;
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Shadow Functions
+ * \{ */
+
/* type */
#define POINT 0.0
#define SUN 1.0
@@ -133,9 +210,11 @@ float sample_cascade_shadow(int shadow_id, vec3 W)
#undef scube
#undef scsmd
-/* ----------------------------------------------------------- */
-/* --------------------- Light Functions --------------------- */
-/* ----------------------------------------------------------- */
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Light Functions
+ * \{ */
/* From Frostbite PBR Course
* Distance based attenuation
@@ -258,7 +337,6 @@ float light_visibility(LightData ld,
l_atten);
}
-#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
if (ld.l_type == AREA_RECT) {
@@ -321,4 +399,5 @@ float light_specular(LightData ld, vec4 ltc_mat, vec3 N, vec3 V, vec4 l_vector)
return ltc_evaluate_disk(N, V, ltc_matrix(ltc_mat), points);
}
}
-#endif
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl
index 8c876cf582c..9077b414026 100644
--- a/source/blender/draw/engines/eevee/shaders/default_world_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lookdev_world_frag.glsl
@@ -1,20 +1,17 @@
-uniform float backgroundAlpha;
-uniform vec3 color;
-
-out vec4 FragColor;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
-#if defined(LOOKDEV_BG) || defined(LOOKDEV)
+uniform sampler2D studioLight;
+uniform float backgroundAlpha;
uniform mat3 StudioLightMatrix;
-uniform sampler2D image;
uniform float studioLightIntensity = 1.0;
uniform float studioLightBlur = 0.0;
-in vec3 viewPosition;
-# ifndef M_PI
-# define M_PI 3.14159265358979323846
-# endif
+out vec4 FragColor;
vec3 background_transform_to_world(vec3 viewvec)
{
@@ -35,36 +32,20 @@ vec4 node_tex_environment_equirectangular(vec3 co, sampler2D ima)
vec3 nco = normalize(co);
float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
-
- /* Fix pole bleeding */
- float width = float(textureSize(ima, 0).x);
- float texel_width = 1.0 / width;
- v = clamp(v, texel_width, 1.0 - texel_width);
-
- /* Fix u = 0 seam */
- /* This is caused by texture filtering, since uv don't have smooth derivatives
- * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
- * texels. So we force the highest mipmap and don't do anisotropic filtering. */
return textureLod(ima, vec2(u, v), 0.0);
}
-#endif
void main()
{
- vec3 background_color;
+ vec3 worldvec = background_transform_to_world(viewPosition);
+ vec3 background_color;
#if defined(LOOKDEV_BG)
- vec3 worldvec = background_transform_to_world(viewPosition);
background_color = probe_evaluate_world_spec(worldvec, studioLightBlur).rgb;
- background_color *= studioLightIntensity;
-
-#elif defined(LOOKDEV)
- vec3 worldvec = background_transform_to_world(viewPosition);
- background_color = node_tex_environment_equirectangular(StudioLightMatrix * worldvec, image).rgb;
- background_color *= studioLightIntensity;
-
#else
- background_color = color;
+ worldvec = StudioLightMatrix * worldvec;
+ background_color = node_tex_environment_equirectangular(worldvec, studioLight).rgb;
+ background_color *= studioLightIntensity;
#endif
FragColor = vec4(clamp(background_color, vec3(0.0), vec3(1e10)), 1.0) * backgroundAlpha;
diff --git a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
index dbfc7ad5a71..2750d42a74a 100644
--- a/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ltc_lib.glsl
@@ -8,12 +8,6 @@
#define USE_LTC
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
-
/* Diffuse *clipped* sphere integral. */
float diffuse_sphere_integral(float avg_dir_z, float form_factor)
{
diff --git a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
index 95cd69ba310..ef96bcbaedb 100644
--- a/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/object_motion_vert.glsl
@@ -1,4 +1,7 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+
uniform mat4 currModelMatrix;
uniform mat4 prevModelMatrix;
uniform mat4 nextModelMatrix;
@@ -19,6 +22,8 @@ out vec3 nextWorldPos;
void main()
{
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
#ifdef HAIR
bool is_persp = (ProjectionMatrix[3][3] == 0.0);
float time, thick_time, thickness;
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
index 9acd8f998f6..34999076f9c 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_frag.glsl
@@ -1,4 +1,14 @@
+/* Required by some nodes. */
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lit_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
#ifdef USE_ALPHA_HASH
/* From the paper "Hashed Alpha Testing" by Chris Wyman and Morgan McGuire */
@@ -56,8 +66,6 @@ float hashed_alpha_threshold(vec3 co)
#endif
-#define NODETREE_EXEC
-
void main()
{
#if defined(USE_ALPHA_HASH)
@@ -66,11 +74,9 @@ void main()
float opacity = saturate(1.0 - avg(cl.transmittance));
-# if defined(USE_ALPHA_HASH)
/* Hashed Alpha Testing */
if (opacity < hashed_alpha_threshold(worldPosition)) {
discard;
}
-# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
index 2c7e0aca3fb..f650e2eeb8c 100644
--- a/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/prepass_vert.glsl
@@ -1,16 +1,14 @@
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
#ifndef HAIR_SHADER
in vec3 pos;
#endif
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
float time, thick_time, thickness;
@@ -34,5 +32,4 @@ void main()
#ifdef CLIP_PLANES
gl_ClipDistance[0] = dot(vec4(worldPosition.xyz, 1.0), clipPlanes[0]);
#endif
- /* TODO motion vectors */
}
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index f88cfdf3787..39db39f8756 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -1,3 +1,11 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_uniforms_lib.glsl)
+
+uniform sampler2D maxzBuffer;
+uniform sampler2DArray planarDepth;
+
#define MAX_STEP 256
float sample_depth(vec2 uv, int index, float lod)
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
new file mode 100644
index 00000000000..36cf3cecf40
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
@@ -0,0 +1,43 @@
+
+/* ---------------------------------------------------------------------- */
+/** \name Resources
+ * \{ */
+
+layout(std140) uniform renderpass_block
+{
+ bool renderPassDiffuse;
+ bool renderPassDiffuseLight;
+ bool renderPassGlossy;
+ bool renderPassGlossyLight;
+ bool renderPassEmit;
+ bool renderPassSSSColor;
+ bool renderPassEnvironment;
+};
+
+/** \} */
+
+/* ---------------------------------------------------------------------- */
+/** \name Functions
+ * \{ */
+
+vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
+{
+ return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
+}
+
+vec3 render_pass_sss_mask(vec3 sss_color)
+{
+ return renderPassSSSColor ? sss_color : vec3(0.0);
+}
+
+vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
+{
+ return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
+}
+
+vec3 render_pass_emission_mask(vec3 emission_light)
+{
+ return renderPassEmit ? emission_light : vec3(0.0);
+}
+
+/** \} */
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 361963d5ac3..89a411bc7cb 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -1,3 +1,7 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+
#define PASS_POST_UNDEFINED 0
#define PASS_POST_ACCUMULATED_COLOR 1
#define PASS_POST_ACCUMULATED_LIGHT 2
@@ -9,6 +13,8 @@
uniform int postProcessType;
uniform int currentSample;
+
+uniform sampler2D depthBuffer;
uniform sampler2D inputBuffer;
uniform sampler2D inputSecondLightBuffer;
uniform sampler2D inputColorBuffer;
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
index 860ec9e1727..e0b9d4a60db 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
@@ -1,11 +1,11 @@
-out vec4 fragColor;
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+
+uniform sampler2D depthBuffer;
-#ifndef UTIL_TEX
-# define UTIL_TEX
-uniform sampler2DArray utilTex;
-# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
-#endif /* UTIL_TEX */
+out vec4 fragColor;
void main()
{
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index c42f905cf7e..0e342938396 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -1,39 +1,23 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
in vec3 pos;
in vec3 nor;
-#ifdef MESH_SHADER
-out vec3 worldPosition;
-out vec3 viewPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
-
-#ifdef HAIR_SHADER
-out vec3 hairTangent;
-out float hairThickTime;
-out float hairThickness;
-out float hairTime;
-flat out int hairStrandID;
-#endif
-
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();
- vec3 world_pos, binor;
+ vec3 pos, binor;
hair_get_pos_tan_binor_time((ProjectionMatrix[3][3] == 0.0),
ModelMatrixInverse,
ViewMatrixInverse[3].xyz,
ViewMatrixInverse[2].xyz,
- world_pos,
+ pos,
hairTangent,
binor,
hairTime,
@@ -41,6 +25,7 @@ void main()
hairThickTime);
worldNormal = cross(hairTangent, binor);
+ vec3 world_pos = pos;
#else
vec3 world_pos = point_object_to_world(pos);
#endif
@@ -57,7 +42,10 @@ void main()
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
- pass_attr(pos);
+# ifdef HAIR_SHADER
+ pos = hair_get_strand_pos();
+# endif
+ pass_attr(pos, NormalMatrix, ModelMatrixInverse);
# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
index 0591b247541..29495e98355 100644
--- a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -1,3 +1,10 @@
+
+#pragma BLENDER_REQUIRE(common_math_geom_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_common_lib.glsl)
+#pragma BLENDER_REQUIRE(bsdf_sampling_lib.glsl)
+#pragma BLENDER_REQUIRE(raytrace_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
/* ------------ Refraction ------------ */
#define BTDF_BIAS 0.85
diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
new file mode 100644
index 00000000000..e746acfdfa3
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl
@@ -0,0 +1,89 @@
+
+/* Required by some nodes. */
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_utiltex_lib.glsl)
+
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lit_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
+#ifdef USE_ALPHA_BLEND
+/* Use dual source blending to be able to make a whole range of effects. */
+layout(location = 0, index = 0) out vec4 outRadiance;
+layout(location = 0, index = 1) out vec4 outTransmittance;
+
+#else /* OPAQUE */
+layout(location = 0) out vec4 outRadiance;
+layout(location = 1) out vec2 ssrNormals;
+layout(location = 2) out vec4 ssrData;
+# ifdef USE_SSS
+layout(location = 3) out vec3 sssIrradiance;
+layout(location = 4) out float sssRadius;
+layout(location = 5) out vec3 sssAlbedo;
+# endif
+
+#endif
+
+void main()
+{
+ Closure cl = nodetree_exec();
+
+ float holdout = saturate(1.0 - cl.holdout);
+ float transmit = saturate(avg(cl.transmittance));
+ float alpha = 1.0 - transmit;
+
+#ifdef USE_ALPHA_BLEND
+ vec2 uvs = gl_FragCoord.xy * volCoordScale.zw;
+ vec3 vol_transmit, vol_scatter;
+ volumetric_resolve(uvs, gl_FragCoord.z, vol_transmit, vol_scatter);
+
+ /* Removes part of the volume scattering that have
+ * already been added to the destination pixels.
+ * Since we do that using the blending pipeline we need to account for material transmittance. */
+ vol_scatter -= vol_scatter * cl.transmittance;
+
+ cl.radiance = cl.radiance * holdout * vol_transmit + vol_scatter;
+ outRadiance = vec4(cl.radiance, alpha * holdout);
+ outTransmittance = vec4(cl.transmittance, transmit) * holdout;
+#else
+ outRadiance = vec4(cl.radiance, holdout);
+ ssrNormals = cl.ssr_normal;
+ ssrData = cl.ssr_data;
+# ifdef USE_SSS
+ sssIrradiance = cl.sss_irradiance;
+ sssRadius = cl.sss_radius;
+ sssAlbedo = cl.sss_albedo;
+# endif
+#endif
+
+ /* For Probe capture */
+#ifdef USE_SSS
+ float fac = float(!sssToggle);
+
+ /* TODO(fclem) we shouldn't need this.
+ * Just disable USE_SSS when USE_REFRACTION is enabled. */
+# ifdef USE_REFRACTION
+ /* SSRefraction pass is done after the SSS pass.
+ * In order to not loose the diffuse light totally we
+ * need to merge the SSS radiance to the main radiance. */
+ fac = 1.0;
+# endif
+
+ outRadiance.rgb += cl.sss_irradiance.rgb * cl.sss_albedo.rgb * fac;
+#endif
+
+#ifndef USE_ALPHA_BLEND
+ float alpha_div = 1.0 / max(1e-8, alpha);
+ outRadiance.rgb *= alpha_div;
+ ssrData.rgb *= alpha_div;
+# ifdef USE_SSS
+ sssAlbedo.rgb *= alpha_div;
+# endif
+#endif
+
+#ifdef LOOKDEV
+ /* Lookdev spheres are rendered in front. */
+ gl_FragDepth = 0.0;
+#endif
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_geom.glsl b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl
new file mode 100644
index 00000000000..ad437dca79a
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_geom.glsl
@@ -0,0 +1,46 @@
+
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices = 3) out;
+
+RESOURCE_ID_VARYING
+
+/* Only used to compute barycentric coordinates. */
+
+void main()
+{
+#ifdef DO_BARYCENTRIC_DISTANCES
+ dataAttrOut.barycentricDist = calc_barycentric_distances(
+ dataIn[0].worldPosition, dataIn[1].worldPosition, dataIn[2].worldPosition);
+#endif
+
+ PASS_RESOURCE_ID
+
+#ifdef USE_ATTR
+ pass_attr(0);
+#endif
+ PASS_SURFACE_INTERFACE(0);
+ gl_Position = gl_in[0].gl_Position;
+ gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0];
+ EmitVertex();
+
+#ifdef USE_ATTR
+ pass_attr(1);
+#endif
+ PASS_SURFACE_INTERFACE(1);
+ gl_Position = gl_in[1].gl_Position;
+ gl_ClipDistance[0] = gl_in[1].gl_ClipDistance[0];
+ EmitVertex();
+
+#ifdef USE_ATTR
+ pass_attr(2);
+#endif
+ PASS_SURFACE_INTERFACE(2);
+ gl_Position = gl_in[2].gl_Position;
+ gl_ClipDistance[0] = gl_in[2].gl_ClipDistance[0];
+ EmitVertex();
+
+ EndPrimitive();
+}
diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
new file mode 100644
index 00000000000..b93a3a23eff
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl
@@ -0,0 +1,43 @@
+/** This describe the entire interface of the shader. */
+
+/* Samplers */
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
+
+/* Uniforms */
+uniform float refractionDepth;
+
+#define SURFACE_INTERFACE \
+ vec3 worldPosition; \
+ vec3 viewPosition; \
+ vec3 worldNormal; \
+ vec3 viewNormal;
+
+#ifdef GPU_GEOMETRY_SHADER
+in ShaderStageInterface{SURFACE_INTERFACE} dataIn[];
+
+out ShaderStageInterface{SURFACE_INTERFACE} dataOut;
+
+# define PASS_SURFACE_INTERFACE(vert) \
+ dataOut.worldPosition = dataIn[vert].worldPosition; \
+ dataOut.viewPosition = dataIn[vert].viewPosition; \
+ dataOut.worldNormal = dataIn[vert].worldNormal; \
+ dataOut.viewNormal = dataIn[vert].viewNormal;
+
+#else
+
+IN_OUT ShaderStageInterface{SURFACE_INTERFACE};
+
+#endif
+
+#ifdef HAIR_SHADER
+IN_OUT ShaderHairInterface
+{
+ /* world space */
+ vec3 hairTangent;
+ float hairThickTime;
+ float hairThickness;
+ float hairTime;
+ flat int hairStrandID;
+};
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
index 1b94fc2bee1..0ad1393dd70 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl
@@ -1,32 +1,20 @@
+#pragma BLENDER_REQUIRE(common_hair_lib.glsl)
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+#pragma BLENDER_REQUIRE(surface_lib.glsl)
+
#ifndef HAIR_SHADER
in vec3 pos;
in vec3 nor;
#endif
-#ifdef MESH_SHADER
-out vec3 worldPosition;
-out vec3 viewPosition;
-out vec3 worldNormal;
-out vec3 viewNormal;
-#endif
-
-#ifdef HAIR_SHADER
-out vec3 hairTangent;
-out float hairThickTime;
-out float hairThickness;
-out float hairTime;
-flat out int hairStrandID;
-#endif
+RESOURCE_ID_VARYING
void main()
{
-#ifdef GPU_INTEL
- /* Due to some shader compiler bug, we somewhat
- * need to access gl_VertexID to make it work. even
- * if it's actually dead code. */
- gl_Position.x = float(gl_VertexID);
-#endif
+ GPU_INTEL_VERTEX_SHADER_WORKAROUND
+
+ PASS_RESOURCE_ID
#ifdef HAIR_SHADER
hairStrandID = hair_get_strand_id();
@@ -63,7 +51,10 @@ void main()
/* No need to normalize since this is just a rotation. */
viewNormal = normal_world_to_view(worldNormal);
# ifdef USE_ATTR
- pass_attr(pos);
+# ifdef HAIR_SHADER
+ pos = hair_get_strand_pos();
+# endif
+ pass_attr(pos, NormalMatrix, ModelMatrixInverse);
# endif
#endif
}
diff --git a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
index 02ad2170f06..0c01c46c2ba 100644
--- a/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/update_noise_frag.glsl
@@ -1,11 +1,11 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D blueNoise;
uniform vec3 offsets;
out vec4 FragColor;
-#define M_2PI 6.28318530717958647692
-
void main(void)
{
vec3 blue_noise = texelFetch(blueNoise, ivec2(gl_FragCoord.xy), 0).xyz;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
index 312fc07054a..bac69ab0355 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl
@@ -1,9 +1,10 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+#pragma BLENDER_REQUIRE(closure_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
-#define NODETREE_EXEC
-
#ifdef MESH_SHADER
uniform vec3 volumeOrcoLoc;
uniform vec3 volumeOrcoSize;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
index 96b891c929f..30cda401284 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_geom.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
#ifdef MESH_SHADER
/* TODO tight slices */
layout(triangles) in;
@@ -12,12 +14,16 @@ in vec4 vPos[];
flat out int slice;
+RESOURCE_ID_VARYING
+
#ifdef MESH_SHADER
/* TODO tight slices */
void main()
{
gl_Layer = slice = int(vPos[0].z);
+ PASS_RESOURCE_ID
+
# ifdef USE_ATTR
pass_attr(0);
# endif
@@ -48,6 +54,8 @@ void main()
{
gl_Layer = slice = int(vPos[0].z);
+ PASS_RESOURCE_ID
+
# ifdef USE_ATTR
pass_attr(0);
# endif
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
index c3c442e7b69..f4276bd61bd 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -11,9 +13,11 @@ uniform sampler3D volumeExtinction;
#ifdef USE_VOLUME_OPTI
uniform layout(binding = 0, r11f_g11f_b10f) writeonly restrict image3D finalScattering_img;
uniform layout(binding = 1, r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img;
+
vec3 finalScattering;
vec3 finalTransmittance;
#else
+
flat in int slice;
layout(location = 0) out vec3 finalScattering;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
index 40eb3da42d1..9b852a57ec4 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_lib.glsl
@@ -1,4 +1,8 @@
+#pragma BLENDER_REQUIRE(lights_lib.glsl)
+#pragma BLENDER_REQUIRE(lightprobe_lib.glsl)
+#pragma BLENDER_REQUIRE(irradiance_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
@@ -58,7 +62,6 @@ float phase_function(vec3 v, vec3 l, float g)
return (1 - sqr_g) / max(1e-8, 4.0 * M_PI * pow(1 + sqr_g - 2 * g * cos_theta, 3.0 / 2.0));
}
-#ifdef LAMPS_LIB
vec3 light_volume(LightData ld, vec4 l_vector)
{
float power;
@@ -95,7 +98,7 @@ vec3 light_volume(LightData ld, vec4 l_vector)
return tint * lum;
}
-# define VOLUMETRIC_SHADOW_MAX_STEP 32.0
+#define VOLUMETRIC_SHADOW_MAX_STEP 32.0
vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
{
@@ -109,7 +112,7 @@ vec3 participating_media_extinction(vec3 wpos, sampler3D volume_extinction)
vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D volume_extinction)
{
-# if defined(VOLUME_SHADOW)
+#if defined(VOLUME_SHADOW)
/* Heterogeneous volume shadows */
float dd = l_vector.w / volShadowSteps;
vec3 L = l_vector.xyz * l_vector.w;
@@ -120,27 +123,24 @@ vec3 light_volume_shadow(LightData ld, vec3 ray_wpos, vec4 l_vector, sampler3D v
shadow *= exp(-s_extinction * dd);
}
return shadow;
-# else
+#else
return vec3(1.0);
-# endif /* VOLUME_SHADOW */
+#endif /* VOLUME_SHADOW */
}
-#endif
-#ifdef IRRADIANCE_LIB
vec3 irradiance_volumetric(vec3 wpos)
{
-# ifdef IRRADIANCE_HL2
+#ifdef IRRADIANCE_HL2
IrradianceData ir_data = load_irradiance_cell(0, vec3(1.0));
vec3 irradiance = ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
ir_data = load_irradiance_cell(0, vec3(-1.0));
irradiance += ir_data.cubesides[0] + ir_data.cubesides[1] + ir_data.cubesides[2];
irradiance *= 0.16666666; /* 1/6 */
return irradiance;
-# else
+#else
return vec3(0.0);
-# endif
-}
#endif
+}
uniform sampler3D inScattering;
uniform sampler3D inTransmittance;
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
index 1ff7e848c40..6ab21587c9a 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_resolve_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
index 9621fa1cc0d..806f1b5b205 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_scatter_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(volumetric_lib.glsl)
+
/* Based on Frosbite Unified Volumetric.
* https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
index b96360febb0..b70747ecec3 100644
--- a/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_vert.glsl
@@ -1,6 +1,10 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
out vec4 vPos;
+RESOURCE_ID_VARYING
+
void main()
{
/* Generate Triangle : less memory fetches from a VBO */
@@ -25,7 +29,9 @@ void main()
vPos.z = float(t_id);
vPos.w = 1.0;
+ PASS_RESOURCE_ID
+
#ifdef USE_ATTR
- pass_attr(vec3(0.0));
+ pass_attr(vec3(0.0), mat3(1), mat4(1));
#endif
}
diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c
index 3ef20dbe9ec..36d295d1dde 100644
--- a/source/blender/draw/engines/external/external_engine.c
+++ b/source/blender/draw/engines/external/external_engine.c
@@ -268,7 +268,7 @@ static void external_draw_scene(void *vedata)
* OpenGL render is used for quick preview (thumbnails or sequencer preview)
* where using the rendering engine to preview doesn't make so much sense. */
if (draw_ctx->evil_C) {
- float clear_col[4] = {0, 0, 0, 0};
+ const float clear_col[4] = {0, 0, 0, 0};
/* This is to keep compatibility with external engine. */
/* TODO(fclem) remove it eventually. */
GPU_framebuffer_bind(dfbl->default_fb);
diff --git a/source/blender/draw/engines/gpencil/gpencil_antialiasing.c b/source/blender/draw/engines/gpencil/gpencil_antialiasing.c
index 8955240c549..b9600ad8caf 100644
--- a/source/blender/draw/engines/gpencil/gpencil_antialiasing.c
+++ b/source/blender/draw/engines/gpencil/gpencil_antialiasing.c
@@ -36,7 +36,7 @@ void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
const float *size = DRW_viewport_size_get();
const float *sizeinv = DRW_viewport_invert_size_get();
- float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]};
+ const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]};
if (pd->simplify_antialias) {
/* No AA fallback. */
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 8a4134ec8ea..363794e1be3 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -132,12 +132,11 @@ static int gpencil_tobject_dist_sort(const void *a, const void *b)
if (ob_a->camera_z > ob_b->camera_z) {
return 1;
}
- else if (ob_a->camera_z < ob_b->camera_z) {
+ if (ob_a->camera_z < ob_b->camera_z) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
void gpencil_object_cache_sort(GPENCIL_PrivateData *pd)
@@ -193,7 +192,7 @@ static float gpencil_layer_final_opacity_get(const GPENCIL_PrivateData *pd,
if (is_obact && is_fade) {
return gpl->opacity * pd->fade_layer_opacity;
}
- else if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) {
+ if (!is_obact && (pd->fade_gp_object_opacity > -1.0f)) {
return gpl->opacity * pd->fade_gp_object_opacity;
}
}
@@ -246,7 +245,7 @@ static void gpencil_layer_random_color_get(const Object *ob,
uint ob_hash = BLI_ghashutil_strhash_p_murmur(ob->id.name);
uint gpl_hash = BLI_ghashutil_strhash_p_murmur(gpl->info);
float hue = BLI_hash_int_01(ob_hash * gpl_hash);
- float hsv[3] = {hue, hsv_saturation, hsv_value};
+ const float hsv[3] = {hue, hsv_saturation, hsv_value};
hsv_to_rgb_v(hsv, r_color);
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
index 6e6b35e19ca..51152475a06 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c
@@ -63,7 +63,7 @@ static struct GPUTexture *gpencil_image_texture_get(Image *image, bool *r_alpha_
ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
if (ibuf != NULL && ibuf->rect != NULL) {
- gpu_tex = GPU_texture_from_blender(image, &iuser, ibuf, GL_TEXTURE_2D);
+ gpu_tex = BKE_image_get_gpu_texture(image, &iuser, ibuf);
*r_alpha_premult = (image->alpha_mode == IMA_ALPHA_PREMUL);
}
BKE_image_release_ibuf(image, ibuf, lock);
@@ -359,12 +359,11 @@ static float light_power_get(const Light *la)
if (la->type == LA_AREA) {
return 1.0f / (4.0f * M_PI);
}
- else if (la->type == LA_SPOT || la->type == LA_LOCAL) {
+ if (la->type == LA_SPOT || la->type == LA_LOCAL) {
return 1.0f / (4.0f * M_PI * M_PI);
}
- else {
- return 1.0f / M_PI;
- }
+
+ return 1.0f / M_PI;
}
void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob)
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index dbad226099e..746920e38c6 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -71,7 +71,7 @@ void GPENCIL_engine_init(void *ved)
}
if (txl->dummy_texture == NULL) {
- float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}};
+ const float pixels[1][4] = {{1.0f, 0.0f, 1.0f, 1.0f}};
txl->dummy_texture = DRW_texture_create_2d(1, 1, GPU_RGBA8, DRW_TEX_WRAP, (float *)pixels);
}
@@ -766,7 +766,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL
{
GPENCIL_PassList *psl = vedata->psl;
GPENCIL_FramebufferList *fbl = vedata->fbl;
- float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f;
bool inverted = false;
/* OPTI(fclem) we could optimize by only clearing if the new mask_bits does not contain all
@@ -813,7 +813,7 @@ static void GPENCIL_draw_object(GPENCIL_Data *vedata, GPENCIL_tObject *ob)
GPENCIL_PassList *psl = vedata->psl;
GPENCIL_PrivateData *pd = vedata->stl->pd;
GPENCIL_FramebufferList *fbl = vedata->fbl;
- float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
+ const float clear_cols[2][4] = {{0.0f, 0.0f, 0.0f, 0.0f}, {1.0f, 1.0f, 1.0f, 1.0f}};
DRW_stats_group_start("GPencil Object");
diff --git a/source/blender/draw/engines/gpencil/gpencil_render.c b/source/blender/draw/engines/gpencil/gpencil_render.c
index 4748858a6a8..df52b65aa78 100644
--- a/source/blender/draw/engines/gpencil/gpencil_render.c
+++ b/source/blender/draw/engines/gpencil/gpencil_render.c
@@ -129,7 +129,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata,
/* To avoid unpredictable result, clear buffers that have not be initialized. */
GPU_framebuffer_bind(fbl->render_fb);
if (do_clear_col) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_clear_color(fbl->render_fb, clear_col);
}
if (do_clear_z) {
@@ -143,9 +143,11 @@ void GPENCIL_render_init(GPENCIL_Data *vedata,
int w = BLI_rcti_size_x(rect);
int h = BLI_rcti_size_y(rect);
if (pix_col) {
+ GPU_texture_bind(txl->render_color_tx, 0);
GPU_texture_update_sub(txl->render_color_tx, GPU_DATA_FLOAT, pix_col, x, y, 0, w, h, 0);
}
if (pix_z) {
+ GPU_texture_bind(txl->render_depth_tx, 0);
GPU_texture_update_sub(txl->render_depth_tx, GPU_DATA_FLOAT, pix_z, x, y, 0, w, h, 0);
}
}
diff --git a/source/blender/draw/engines/overlay/overlay_antialiasing.c b/source/blender/draw/engines/overlay/overlay_antialiasing.c
index a32242d6292..9e95e860d0a 100644
--- a/source/blender/draw/engines/overlay/overlay_antialiasing.c
+++ b/source/blender/draw/engines/overlay/overlay_antialiasing.c
@@ -69,7 +69,7 @@ void OVERLAY_antialiasing_init(OVERLAY_Data *vedata)
/* Small texture which will have very small impact on rendertime. */
if (txl->dummy_depth_tx == NULL) {
- float pixel[1] = {1.0f};
+ const float pixel[1] = {1.0f};
txl->dummy_depth_tx = DRW_texture_create_2d(1, 1, GPU_DEPTH_COMPONENT24, 0, pixel);
}
@@ -202,7 +202,7 @@ void OVERLAY_antialiasing_start(OVERLAY_Data *vedata)
OVERLAY_PrivateData *pd = vedata->stl->pd;
if (pd->antialiasing.enabled) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(fbl->overlay_line_fb);
GPU_framebuffer_clear_color(fbl->overlay_line_fb, clear_col);
}
diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c
index 960e5e424f2..49b8257e0c6 100644
--- a/source/blender/draw/engines/overlay/overlay_armature.c
+++ b/source/blender/draw/engines/overlay/overlay_armature.c
@@ -601,7 +601,7 @@ static void drw_shgroup_bone_custom_empty(ArmatureDrawContext *ctx,
const float color[4],
Object *custom)
{
- float final_color[4] = {color[0], color[1], color[2], 1.0f};
+ const float final_color[4] = {color[0], color[1], color[2], 1.0f};
float mat[4][4];
mul_m4_m4m4(mat, ctx->ob->obmat, bone_mat);
@@ -924,12 +924,11 @@ static float get_bone_wire_thickness(const ArmatureDrawContext *ctx, int bonefla
if (ctx->const_color) {
return ctx->const_wire;
}
- else if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
+ if (boneflag & (BONE_DRAW_ACTIVE | BONE_SELECTED)) {
return 2.0f;
}
- else {
- return 1.0f;
- }
+
+ return 1.0f;
}
static const float *get_bone_wire_color(const ArmatureDrawContext *ctx,
@@ -1079,7 +1078,7 @@ static void edbo_compute_bbone_child(bArmature *arm)
}
/* A version of BKE_pchan_bbone_spline_setup() for previewing editmode curve settings. */
-static void ebone_spline_preview(EditBone *ebone, float result_array[MAX_BBONE_SUBDIV][4][4])
+static void ebone_spline_preview(EditBone *ebone, const float result_array[MAX_BBONE_SUBDIV][4][4])
{
BBoneSplineParameters param;
EditBone *prev, *next;
@@ -2219,13 +2218,13 @@ static bool POSE_is_driven_by_active_armature(Object *ob)
}
return is_active;
}
- else {
- Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
- if (ob_mesh_deform) {
- /* Recursive. */
- return POSE_is_driven_by_active_armature(ob_mesh_deform);
- }
+
+ Object *ob_mesh_deform = BKE_modifiers_is_deformed_by_meshdeform(ob);
+ if (ob_mesh_deform) {
+ /* Recursive. */
+ return POSE_is_driven_by_active_armature(ob_mesh_deform);
}
+
return false;
}
diff --git a/source/blender/draw/engines/overlay/overlay_edit_text.c b/source/blender/draw/engines/overlay/overlay_edit_text.c
index 6ddd0e6d9be..fd68b319f02 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_text.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_text.c
@@ -74,7 +74,7 @@ void OVERLAY_edit_text_cache_init(OVERLAY_Data *vedata)
/* Use 2D quad corners to create a matrix that set
* a [-1..1] quad at the right position. */
-static void v2_quad_corners_to_mat4(float corners[4][2], float r_mat[4][4])
+static void v2_quad_corners_to_mat4(const float corners[4][2], float r_mat[4][4])
{
unit_m4(r_mat);
sub_v2_v2v2(r_mat[0], corners[1], corners[0]);
diff --git a/source/blender/draw/engines/overlay/overlay_engine.c b/source/blender/draw/engines/overlay/overlay_engine.c
index bc96a03da31..1312408498a 100644
--- a/source/blender/draw/engines/overlay/overlay_engine.c
+++ b/source/blender/draw/engines/overlay/overlay_engine.c
@@ -440,7 +440,7 @@ static void OVERLAY_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
if (DRW_state_is_fbo()) {
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_framebuffer_bind(dfbl->overlay_only_fb);
GPU_framebuffer_clear_color(dfbl->overlay_only_fb, clear_col);
}
diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c
index 0b4d0fcdc11..ce678c7d03f 100644
--- a/source/blender/draw/engines/overlay/overlay_extra.c
+++ b/source/blender/draw/engines/overlay/overlay_extra.c
@@ -53,8 +53,6 @@
#include "ED_view3d.h"
-#include "GPU_draw.h"
-
#include "overlay_private.h"
#include "draw_common.h"
@@ -279,7 +277,7 @@ void OVERLAY_extra_wire(OVERLAY_ExtraCallBuffers *cb,
const float color[4])
{
float draw_mat[4][4];
- float col[4] = {UNPACK3(color), 0.0f /* No stipples. */};
+ const float col[4] = {UNPACK3(color), 0.0f /* No stipples. */};
pack_v4_in_mat4(draw_mat, mat, col);
DRW_shgroup_call_obmat(cb->extra_wire, geom, draw_mat);
}
@@ -681,8 +679,8 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob)
DRW_buffer_add_entry(cb->light_spot, color, &instdata);
if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) {
- float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f};
- float color_outside[4] = {1.0f, 1.0f, 1.0f, 0.3f};
+ const float color_inside[4] = {0.0f, 0.0f, 0.0f, 0.5f};
+ const float color_outside[4] = {1.0f, 1.0f, 1.0f, 0.3f};
DRW_buffer_add_entry(cb->light_spot_cone_front, color_inside, &instdata);
DRW_buffer_add_entry(cb->light_spot_cone_back, color_outside, &instdata);
}
@@ -1020,9 +1018,8 @@ static float camera_offaxis_shiftx_get(Scene *scene,
const float width = instdata->corner_x * 2.0f;
return delta_shiftx * width;
}
- else {
- return 0.0;
- }
+
+ return 0.0;
}
/**
* Draw the stereo 3d support elements (cameras, plane, volume).
@@ -1339,7 +1336,7 @@ static void OVERLAY_relationship_lines(OVERLAY_ExtraCallBuffers *cb,
else {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(curcon);
- if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag && (1 << 0))) {
+ if ((cti && cti->get_constraint_targets) && (curcon->ui_expand_flag & (1 << 0))) {
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
@@ -1422,7 +1419,7 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb,
line_count /= fds->res[axis];
}
- GPU_create_smoke_velocity(fmd);
+ DRW_smoke_ensure_velocity(fmd);
GPUShader *sh = OVERLAY_shader_volume_velocity(use_needle);
DRWShadingGroup *grp = DRW_shgroup_create(sh, data->psl->extra_ps[0]);
@@ -1452,7 +1449,7 @@ static void OVERLAY_volume_free_smoke_textures(OVERLAY_Data *data)
LinkData *link;
while ((link = BLI_pophead(&data->stl->pd->smoke_domains))) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke_velocity(fmd);
+ DRW_smoke_free_velocity(fmd);
MEM_freeN(link);
}
}
@@ -1542,7 +1539,7 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob)
}
/* Helpers for when we're transforming origins. */
if (draw_xform) {
- float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f};
+ const float color_xform[4] = {0.15f, 0.15f, 0.15f, 0.7f};
DRW_buffer_add_entry(cb->origin_xform, color_xform, ob->obmat);
}
/* don't show object extras in set's */
diff --git a/source/blender/draw/engines/overlay/overlay_image.c b/source/blender/draw/engines/overlay/overlay_image.c
index 67132a9e0ed..08cddf4e185 100644
--- a/source/blender/draw/engines/overlay/overlay_image.c
+++ b/source/blender/draw/engines/overlay/overlay_image.c
@@ -109,13 +109,12 @@ static eStereoViews camera_background_images_stereo_eye(const Scene *scene, cons
if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return STEREO_LEFT_ID;
}
- else if (v3d->stereo3d_camera != STEREO_3D_ID) {
+ if (v3d->stereo3d_camera != STEREO_3D_ID) {
/* show only left or right camera */
return v3d->stereo3d_camera;
}
- else {
- return v3d->multiview_eye;
- }
+
+ return v3d->multiview_eye;
}
static void camera_background_images_stereo_setup(const Scene *scene,
@@ -162,9 +161,8 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
/* Frame is out of range, dont show. */
return NULL;
}
- else {
- camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
- }
+
+ camera_background_images_stereo_setup(scene, draw_ctx->v3d, image, iuser);
iuser->scene = draw_ctx->scene;
ImBuf *ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
@@ -175,7 +173,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
}
width = ibuf->x;
height = ibuf->y;
- tex = GPU_texture_from_blender(image, iuser, ibuf, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(image, iuser, ibuf);
BKE_image_release_ibuf(image, ibuf, lock);
iuser->scene = NULL;
@@ -203,7 +201,7 @@ static struct GPUTexture *image_camera_background_texture_get(CameraBGImage *bgp
}
BKE_movieclip_user_set_frame(&bgpic->cuser, ctime);
- tex = GPU_texture_from_movieclip(clip, &bgpic->cuser, GL_TEXTURE_2D);
+ tex = BKE_movieclip_get_gpu_texture(clip, &bgpic->cuser);
if (tex == NULL) {
return NULL;
}
@@ -232,7 +230,7 @@ static void OVERLAY_image_free_movieclips_textures(OVERLAY_Data *data)
LinkData *link;
while ((link = BLI_pophead(&data->stl->pd->bg_movie_clips))) {
MovieClip *clip = (MovieClip *)link->data;
- GPU_free_texture_movieclip(clip);
+ BKE_movieclip_free_gputexture(clip);
MEM_freeN(link);
}
}
@@ -342,7 +340,7 @@ void OVERLAY_image_camera_cache_populate(OVERLAY_Data *vedata, Object *ob)
mul_m4_m4m4(mat, modelmat, mat);
const bool is_foreground = (bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != 0;
- float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
+ const float color_premult_alpha[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha};
DRWPass *pass = is_foreground ? psl->image_foreground_ps : psl->image_background_ps;
@@ -383,7 +381,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob)
if (ima != NULL) {
ImageUser iuser = *ob->iuser;
camera_background_images_stereo_setup(draw_ctx->scene, draw_ctx->v3d, ima, &iuser);
- tex = GPU_texture_from_blender(ima, &iuser, NULL, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(ima, &iuser, NULL);
if (tex) {
size[0] = GPU_texture_orig_width(tex);
size[1] = GPU_texture_orig_height(tex);
diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.c b/source/blender/draw/engines/overlay/overlay_motion_path.c
index 168f6f8a17f..0e5a52702fe 100644
--- a/source/blender/draw/engines/overlay/overlay_motion_path.c
+++ b/source/blender/draw/engines/overlay/overlay_motion_path.c
@@ -149,7 +149,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
/* Draw curve-line of path. */
if (show_lines) {
- int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame};
+ const int motion_path_settings[4] = {cfra, sfra, efra, mpath->start_frame};
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_lines_grp);
DRW_shgroup_uniform_ivec4_copy(grp, "mpathLineSettings", motion_path_settings);
DRW_shgroup_uniform_int_copy(grp, "lineThickness", mpath->line_thickness);
@@ -162,7 +162,7 @@ static void motion_path_cache(OVERLAY_Data *vedata,
/* Draw points. */
{
int pt_size = max_ii(mpath->line_thickness - 1, 1);
- int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize};
+ const int motion_path_settings[4] = {pt_size, cfra, mpath->start_frame, stepsize};
DRWShadingGroup *grp = DRW_shgroup_create_sub(pd->motion_path_points_grp);
DRW_shgroup_uniform_ivec4_copy(grp, "mpathPointSettings", motion_path_settings);
DRW_shgroup_uniform_bool_copy(grp, "showKeyFrames", show_keyframes);
diff --git a/source/blender/draw/engines/overlay/overlay_outline.c b/source/blender/draw/engines/overlay/overlay_outline.c
index 214322c4adc..e904066248f 100644
--- a/source/blender/draw/engines/overlay/overlay_outline.c
+++ b/source/blender/draw/engines/overlay/overlay_outline.c
@@ -342,7 +342,7 @@ void OVERLAY_outline_draw(OVERLAY_Data *vedata)
{
OVERLAY_FramebufferList *fbl = vedata->fbl;
OVERLAY_PassList *psl = vedata->psl;
- float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
bool do_outlines = psl->outlines_prepass_ps != NULL &&
!DRW_pass_is_empty(psl->outlines_prepass_ps);
diff --git a/source/blender/draw/engines/overlay/overlay_paint.c b/source/blender/draw/engines/overlay/overlay_paint.c
index e94cc820568..f0a1e77cf05 100644
--- a/source/blender/draw/engines/overlay/overlay_paint.c
+++ b/source/blender/draw/engines/overlay/overlay_paint.c
@@ -22,6 +22,8 @@
#include "DRW_render.h"
+#include "BKE_image.h"
+
#include "DNA_mesh_types.h"
#include "DEG_depsgraph_query.h"
@@ -34,7 +36,7 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
if (v3d->shading.type == OB_WIRE) {
return true;
}
- else if (v3d->shading.type == OB_SOLID) {
+ if (v3d->shading.type == OB_SOLID) {
if (v3d->shading.flag & V3D_SHADING_XRAY) {
return true;
}
@@ -42,8 +44,8 @@ static bool paint_object_is_rendered_transparent(View3D *v3d, Object *ob)
if (ob && v3d->shading.color_type == V3D_SHADING_OBJECT_COLOR) {
return ob->color[3] < 1.0f;
}
- else if (ob && ob->type == OB_MESH && ob->data &&
- v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
+ if (ob && ob->type == OB_MESH && ob->data &&
+ v3d->shading.color_type == V3D_SHADING_MATERIAL_COLOR) {
Mesh *me = ob->data;
for (int i = 0; i < me->totcol; i++) {
Material *mat = me->mat[i];
@@ -136,7 +138,7 @@ void OVERLAY_paint_cache_init(OVERLAY_Data *vedata)
state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ALPHA;
DRW_PASS_CREATE(psl->paint_color_ps, state | pd->clipping_state);
- GPUTexture *tex = GPU_texture_from_blender(imapaint->stencil, NULL, NULL, GL_TEXTURE_2D);
+ GPUTexture *tex = BKE_image_get_gpu_texture(imapaint->stencil, NULL, NULL);
const bool mask_premult = (imapaint->stencil->alpha_mode == IMA_ALPHA_PREMUL);
const bool mask_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0;
diff --git a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
index 0d01f67c6ea..2989e07691f 100644
--- a/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/antialiasing_frag.glsl
@@ -1,4 +1,6 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
uniform sampler2D colorTex;
uniform sampler2D depthTex;
uniform sampler2D lineTex;
diff --git a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
index 380708795e9..0925901a9c9 100644
--- a/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/armature_sphere_solid_frag.glsl
@@ -14,19 +14,6 @@ layout(depth_greater) out float gl_FragDepth;
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 lineOutput;
-#define cameraPos ViewMatrixInverse[3].xyz
-
-float get_depth_from_view_z(float z)
-{
- if (ProjectionMatrix[3][3] == 0.0) {
- z = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
- }
- else {
- z = z * ProjectionMatrix[2][2] / (1.0 - ProjectionMatrix[3][2]);
- }
- return z * 0.5 + 0.5;
-}
-
void main()
{
const float sphere_radius = 0.05;
diff --git a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
index 317e9fe0447..d0b68df0625 100644
--- a/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/grid_frag.glsl
@@ -14,8 +14,6 @@ uniform float meshSize;
uniform float lineKernel = 0.0;
uniform sampler2D depthBuffer;
-#define cameraPos (ViewMatrixInverse[3].xyz)
-
uniform int gridFlag;
#define STEPS_LEN 8
diff --git a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
index 496bb011c74..dd0e771ad93 100644
--- a/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/grid_vert.glsl
@@ -7,8 +7,6 @@ uniform float meshSize;
uniform int gridFlag;
-#define cameraPos (ViewMatrixInverse[3].xyz)
-
#define PLANE_XY (1 << 4)
#define PLANE_XZ (1 << 5)
#define PLANE_YZ (1 << 6)
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
index 722dbdd0b5e..d0d52c8485b 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl
@@ -28,7 +28,7 @@ void cavity_compute(vec2 screenco,
return;
}
- vec3 position = view_position_from_depth(screenco, depth, ViewVecs, ProjectionMatrix);
+ vec3 position = get_view_space_from_depth(screenco, depth);
vec3 normal = workbench_normal_decode(texture(normalBuffer, screenco));
vec2 jitter_co = (screenco * world_data.viewport_size.xy) * world_data.cavity_jitter_scale;
@@ -68,7 +68,7 @@ void cavity_compute(vec2 screenco,
bool is_background = (s_depth == 1.0);
/* This trick provide good edge effect even if no neighbor is found. */
s_depth = (is_background) ? depth : s_depth;
- vec3 s_pos = view_position_from_depth(uvcoords, s_depth, ViewVecs, ProjectionMatrix);
+ vec3 s_pos = get_view_space_from_depth(uvcoords, s_depth);
if (is_background) {
s_pos.z -= world_data.cavity_distance;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
index c529f23265b..eb61edca6c7 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_common_lib.glsl
@@ -67,31 +67,3 @@ void workbench_float_pair_decode(float data, out float v1, out float v2)
v1 = float(idata & v1_mask) * (1.0 / float(v1_mask));
v2 = float(idata >> int(ROUGHNESS_BITS)) * (1.0 / float(v2_mask));
}
-
-vec3 view_vector_from_screen_uv(vec2 uv, vec4 viewvecs[2], mat4 proj_mat)
-{
- if (proj_mat[3][3] == 0.0) {
- return normalize(vec3(viewvecs[0].xy + uv * viewvecs[1].xy, 1.0));
- }
- else {
- return vec3(0.0, 0.0, 1.0);
- }
-}
-
-vec3 view_position_from_depth(vec2 uvcoords, float depth, vec4 viewvecs[2], mat4 proj_mat)
-{
- if (proj_mat[3][3] == 0.0) {
- /* Perspective */
- float d = 2.0 * depth - 1.0;
-
- float zview = -proj_mat[3][2] / (d + proj_mat[2][2]);
-
- return zview * vec3(viewvecs[0].xy + uvcoords * viewvecs[1].xy, 1.0);
- }
- else {
- /* Orthographic */
- vec3 offset = vec3(uvcoords, depth);
-
- return viewvecs[0].xyz + offset * viewvecs[1].xyz;
- }
-}
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
index f3a238fd112..6e10a656fc1 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl
@@ -14,7 +14,7 @@ out vec4 fragColor;
void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
- vec3 I = view_vector_from_screen_uv(uvcoordsvar.st, ViewVecs, ProjectionMatrix);
+ vec3 I = get_view_vector_from_screen_uv(uvcoordsvar.st);
vec3 N = workbench_normal_decode(texture(normalBuffer, uvcoordsvar.st));
vec4 mat_data = texture(materialBuffer, uvcoordsvar.st);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
index 51007a9f246..71816f6ff6e 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_effect_dof_frag.glsl
@@ -1,3 +1,6 @@
+
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
+
/**
* Separable Hexagonal Bokeh Blur by Colin Barré-Brisebois
* https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited-part-1-basic-3-pass-version/
@@ -21,13 +24,6 @@ uniform sampler2D noiseTex;
#define dof_distance dofParams.y
#define dof_invsensorsize dofParams.z
-#define M_PI 3.1415926535897932 /* pi */
-
-float max_v4(vec4 v)
-{
- return max(max(v.x, v.y), max(v.z, v.w));
-}
-
#define weighted_sum(a, b, c, d, e, e_sum) \
((a)*e.x + (b)*e.y + (c)*e.z + (d)*e.w) / max(1e-6, e_sum);
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
index ba8eeff1001..fd4d00d96dd 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl
@@ -57,7 +57,7 @@ void main()
{
/* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */
vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv;
- vec3 I = view_vector_from_screen_uv(uv_viewport, ViewVecs, ProjectionMatrix);
+ vec3 I = get_view_vector_from_screen_uv(uv_viewport);
vec3 N = normalize(normal_interp);
vec3 color = color_interp;
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
index 6ab652cbf36..aa938d80fa3 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl
@@ -1,4 +1,5 @@
+#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_common_obinfos_lib.glsl)
#pragma BLENDER_REQUIRE(workbench_data_lib.glsl)
@@ -33,11 +34,6 @@ float phase_function_isotropic()
return 1.0 / (4.0 * M_PI);
}
-float max_v3(vec3 v)
-{
- return max(v.x, max(v.y, v.z));
-}
-
float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
{
/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
@@ -194,8 +190,8 @@ void main()
float depth = texelFetch(depthBuffer, ivec2(gl_FragCoord.xy), 0).r;
float depth_end = min(depth, gl_FragCoord.z);
- vec3 vs_ray_end = view_position_from_depth(screen_uv, depth_end, ViewVecs, ProjectionMatrix);
- vec3 vs_ray_ori = view_position_from_depth(screen_uv, 0.0, ViewVecs, ProjectionMatrix);
+ vec3 vs_ray_end = get_view_space_from_depth(screen_uv, depth_end);
+ vec3 vs_ray_ori = get_view_space_from_depth(screen_uv, 0.0);
vec3 vs_ray_dir = (is_persp) ? (vs_ray_end - vs_ray_ori) : vec3(0.0, 0.0, -1.0);
vs_ray_dir /= abs(vs_ray_dir.z);
diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
index 0e896c4b7bb..47a03073839 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.c
@@ -112,17 +112,15 @@ int workbench_antialiasing_sample_count_get(WORKBENCH_PrivateData *wpd)
/* Only draw using SMAA or no AA when navigating. */
return min_ii(wpd->preferences->viewport_aa, 1);
}
- else if (DRW_state_is_image_render()) {
+ if (DRW_state_is_image_render()) {
if (draw_ctx->v3d) {
return scene->display.viewport_aa;
}
- else {
- return scene->display.render_aa;
- }
- }
- else {
- return wpd->preferences->viewport_aa;
+
+ return scene->display.render_aa;
}
+
+ return wpd->preferences->viewport_aa;
}
void workbench_antialiasing_view_updated(WORKBENCH_Data *vedata)
@@ -303,7 +301,7 @@ void workbench_antialiasing_cache_init(WORKBENCH_Data *vedata)
const float *size = DRW_viewport_size_get();
const float *sizeinv = DRW_viewport_invert_size_get();
- float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]};
+ const float metrics[4] = {sizeinv[0], sizeinv[1], size[0], size[1]};
{
/* Stage 1: Edge detection. */
@@ -361,53 +359,52 @@ bool workbench_antialiasing_setup(WORKBENCH_Data *vedata)
/* TAA accumulation has finish. Just copy the result back */
return false;
}
- else {
- const float *viewport_size = DRW_viewport_size_get();
- const DRWView *default_view = DRW_view_default_get();
- float *transform_offset;
-
- switch (wpd->taa_sample_len) {
- default:
- case 5:
- transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)];
- break;
- case 8:
- transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)];
- break;
- case 11:
- transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)];
- break;
- case 16:
- transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)];
- break;
- case 32:
- transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)];
- break;
- }
-
- /* construct new matrices from transform delta */
- float winmat[4][4], viewmat[4][4], persmat[4][4];
- DRW_view_winmat_get(default_view, winmat, false);
- DRW_view_viewmat_get(default_view, viewmat, false);
- DRW_view_persmat_get(default_view, persmat, false);
- window_translate_m4(winmat,
- persmat,
- transform_offset[0] / viewport_size[0],
- transform_offset[1] / viewport_size[1]);
-
- if (wpd->view) {
- /* When rendering just update the view. This avoids recomputing the culling. */
- DRW_view_update_sub(wpd->view, viewmat, winmat);
- }
- else {
- /* TAA is not making a big change to the matrices.
- * Reuse the main view culling by creating a sub-view. */
- wpd->view = DRW_view_create_sub(default_view, viewmat, winmat);
- }
- DRW_view_set_active(wpd->view);
- return true;
+ const float *viewport_size = DRW_viewport_size_get();
+ const DRWView *default_view = DRW_view_default_get();
+ float *transform_offset;
+
+ switch (wpd->taa_sample_len) {
+ default:
+ case 5:
+ transform_offset = e_data.jitter_5[min_ii(wpd->taa_sample, 5)];
+ break;
+ case 8:
+ transform_offset = e_data.jitter_8[min_ii(wpd->taa_sample, 8)];
+ break;
+ case 11:
+ transform_offset = e_data.jitter_11[min_ii(wpd->taa_sample, 11)];
+ break;
+ case 16:
+ transform_offset = e_data.jitter_16[min_ii(wpd->taa_sample, 16)];
+ break;
+ case 32:
+ transform_offset = e_data.jitter_32[min_ii(wpd->taa_sample, 32)];
+ break;
+ }
+
+ /* construct new matrices from transform delta */
+ float winmat[4][4], viewmat[4][4], persmat[4][4];
+ DRW_view_winmat_get(default_view, winmat, false);
+ DRW_view_viewmat_get(default_view, viewmat, false);
+ DRW_view_persmat_get(default_view, persmat, false);
+
+ window_translate_m4(winmat,
+ persmat,
+ transform_offset[0] / viewport_size[0],
+ transform_offset[1] / viewport_size[1]);
+
+ if (wpd->view) {
+ /* When rendering just update the view. This avoids recomputing the culling. */
+ DRW_view_update_sub(wpd->view, viewmat, winmat);
+ }
+ else {
+ /* TAA is not making a big change to the matrices.
+ * Reuse the main view culling by creating a sub-view. */
+ wpd->view = DRW_view_create_sub(default_view, viewmat, winmat);
}
+ DRW_view_set_active(wpd->view);
+ return true;
}
void workbench_antialiasing_draw_pass(WORKBENCH_Data *vedata)
diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.c b/source/blender/draw/engines/workbench/workbench_effect_dof.c
index e13f7bfdd92..f2f75d616ff 100644
--- a/source/blender/draw/engines/workbench/workbench_effect_dof.c
+++ b/source/blender/draw/engines/workbench/workbench_effect_dof.c
@@ -155,7 +155,7 @@ void workbench_dof_engine_init(WORKBENCH_Data *vedata)
}
const float *full_size = DRW_viewport_size_get();
- int size[2] = {max_ii(1, (int)full_size[0] / 2), max_ii(1, (int)full_size[1] / 2)};
+ const int size[2] = {max_ii(1, (int)full_size[0] / 2), max_ii(1, (int)full_size[1] / 2)};
#if 0 /* TODO(fclem) finish COC min_max optimisation */
/* NOTE: We Ceil here in order to not miss any edge texel if using a NPO2 texture. */
int shrink_h_size[2] = {ceilf(size[0] / 8.0f), size[1]};
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 53119723fab..ca80b6a9002 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -64,7 +64,7 @@ void workbench_engine_init(void *ved)
workbench_update_world_ubo(wpd);
if (txl->dummy_image_tx == NULL) {
- float fpixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
+ const float fpixel[4] = {1.0f, 0.0f, 1.0f, 1.0f};
txl->dummy_image_tx = DRW_texture_create_2d(1, 1, GPU_RGBA8, 0, fpixel);
}
wpd->dummy_image_tx = txl->dummy_image_tx;
@@ -480,8 +480,8 @@ void workbench_draw_sample(void *ved)
WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
WORKBENCH_PassList *psl = vedata->psl;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float clear_col_with_alpha[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float clear_col_with_alpha[4] = {0.0f, 0.0f, 0.0f, 1.0f};
const bool do_render = workbench_antialiasing_setup(vedata);
const bool xray_is_visible = wpd->shading.xray_alpha > 0.0f;
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index 4d5a5b163ed..538083b4beb 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -60,7 +60,7 @@ void workbench_material_ubo_data(WORKBENCH_PrivateData *wpd,
hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob->id.lib->filepath);
}
float hue = BLI_hash_int_01(hash);
- float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
+ const float hsv[3] = {hue, HSV_SATURATION, HSV_VALUE};
hsv_to_rgb_v(hsv, data->base_color);
break;
}
@@ -261,11 +261,11 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
if (ima) {
if (ima->source == IMA_SRC_TILED) {
- tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D_ARRAY);
- tex_tile_data = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_1D_ARRAY);
+ tex = BKE_image_get_gpu_tiles(ima, iuser, NULL);
+ tex_tile_data = BKE_image_get_gpu_tilemap(ima, iuser, NULL);
}
else {
- tex = GPU_texture_from_blender(ima, iuser, NULL, GL_TEXTURE_2D);
+ tex = BKE_image_get_gpu_texture(ima, iuser, NULL);
}
}
diff --git a/source/blender/draw/engines/workbench/workbench_shader.c b/source/blender/draw/engines/workbench/workbench_shader.c
index 835f10598d4..aab3cef00e6 100644
--- a/source/blender/draw/engines/workbench/workbench_shader.c
+++ b/source/blender/draw/engines/workbench/workbench_shader.c
@@ -28,6 +28,8 @@
#include "workbench_engine.h"
#include "workbench_private.h"
+extern char datatoc_common_math_lib_glsl[];
+extern char datatoc_common_math_geom_lib_glsl[];
extern char datatoc_common_hair_lib_glsl[];
extern char datatoc_common_pointcloud_lib_glsl[];
extern char datatoc_common_view_lib_glsl[];
@@ -119,6 +121,8 @@ void workbench_shader_library_ensure(void)
if (e_data.lib == NULL) {
e_data.lib = DRW_shader_library_create();
/* NOTE: Theses needs to be ordered by dependencies. */
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_math_geom_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_hair_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_pointcloud_lib);
diff --git a/source/blender/draw/engines/workbench/workbench_shadow.c b/source/blender/draw/engines/workbench/workbench_shadow.c
index 2cf5f3c4c13..56a028d5a7e 100644
--- a/source/blender/draw/engines/workbench/workbench_shadow.c
+++ b/source/blender/draw/engines/workbench/workbench_shadow.c
@@ -62,7 +62,7 @@ static void workbench_shadow_update(WORKBENCH_PrivateData *wpd)
wpd->shadow_cached_direction, wpd->shadow_direction_ws, 1e-5f);
if (wpd->shadow_changed) {
- float up[3] = {0.0f, 0.0f, 1.0f};
+ const float up[3] = {0.0f, 0.0f, 1.0f};
unit_m4(wpd->shadow_mat);
/* TODO fix singularity. */
@@ -229,7 +229,7 @@ static float workbench_shadow_object_shadow_distance(WORKBENCH_PrivateData *wpd,
{
BoundBox *shadow_bbox = workbench_shadow_object_shadow_bbox_get(wpd, ob, oed);
- int corners[4] = {0, 3, 4, 7};
+ const int corners[4] = {0, 3, 4, 7};
float dist = 1e4f, dist_isect;
for (int i = 0; i < 4; i++) {
if (isect_ray_plane_v3(shadow_bbox->vec[corners[i]],
diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c
index 8e345f8275b..f71e77d5da5 100644
--- a/source/blender/draw/engines/workbench/workbench_volume.c
+++ b/source/blender/draw/engines/workbench/workbench_volume.c
@@ -38,15 +38,13 @@
#include "BKE_volume.h"
#include "BKE_volume_render.h"
-#include "GPU_draw.h"
-
void workbench_volume_engine_init(WORKBENCH_Data *vedata)
{
WORKBENCH_TextureList *txl = vedata->txl;
if (txl->dummy_volume_tx == NULL) {
- float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
txl->dummy_volume_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, zero, NULL);
txl->dummy_shadow_tx = GPU_texture_create_3d(1, 1, 1, GPU_RGBA8, one, NULL);
txl->dummy_coba_tx = GPU_texture_create_1d(1, GPU_RGBA8, zero, NULL);
@@ -79,13 +77,10 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata,
wpd->volumes_do = true;
if (fds->use_coba) {
- GPU_create_smoke_coba_field(fmd);
- }
- else if (!(fds->flags & FLUID_DOMAIN_USE_NOISE)) {
- GPU_create_smoke(fmd, 0);
+ DRW_smoke_ensure_coba_field(fmd);
}
- else if (fds->flags & FLUID_DOMAIN_USE_NOISE) {
- GPU_create_smoke(fmd, 1);
+ else {
+ DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
}
if ((!fds->use_coba && (fds->tex_density == NULL && fds->tex_color == NULL)) ||
@@ -293,7 +288,7 @@ void workbench_volume_draw_finish(WORKBENCH_Data *vedata)
* all viewport in a redraw at least. */
LISTBASE_FOREACH (LinkData *, link, &wpd->smoke_domains) {
FluidModifierData *fmd = (FluidModifierData *)link->data;
- GPU_free_smoke(fmd);
+ DRW_smoke_free(fmd);
}
BLI_freelistN(&wpd->smoke_domains);
}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ab6ea53261f..956bddfb357 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -197,6 +197,17 @@ void DRW_uniformbuffer_free(struct GPUUniformBuffer *ubo);
} while (0)
/* Shaders */
+
+#ifndef __GPU_MATERIAL_H__
+/* FIXME: Meh avoid including all GPUMaterial. */
+typedef void (*GPUMaterialEvalCallbackFn)(struct GPUMaterial *mat,
+ int options,
+ const char **vert_code,
+ const char **geom_code,
+ const char **frag_lib,
+ const char **defines);
+#endif
+
struct GPUShader *DRW_shader_create(const char *vert,
const char *geom,
const char *frag,
@@ -236,7 +247,8 @@ struct GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred);
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback);
struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
struct Material *ma,
struct bNodeTree *ntree,
@@ -247,7 +259,8 @@ struct GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred);
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback);
void DRW_shader_free(struct GPUShader *shader);
#define DRW_SHADER_FREE_SAFE(shader) \
do { \
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 20e346375a7..d59c891fbeb 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -361,8 +361,8 @@ GPUBatch *DRW_cache_fullscreen_quad_get(void)
if (!SHC.drw_fullscreen_quad) {
/* Use a triangle instead of a real quad */
/* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */
- float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}};
- float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}};
+ const float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}};
+ const float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}};
/* Position Only 2D format */
static GPUVertFormat format = {0};
@@ -400,7 +400,7 @@ GPUBatch *DRW_cache_quad_get(void)
int v = 0;
int flag = VCLASS_EMPTY_SCALED;
- float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
+ const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
for (int a = 0; a < 4; a++) {
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a][0], p[a][1], 0.0f}, flag});
}
@@ -421,7 +421,7 @@ GPUBatch *DRW_cache_quad_wires_get(void)
int v = 0;
int flag = VCLASS_EMPTY_SCALED;
- float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
+ const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
for (int a = 0; a < 5; a++) {
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a % 4][0], p[a % 4][1], 0.0f}, flag});
}
@@ -1650,7 +1650,7 @@ GPUBatch *DRW_cache_light_area_square_lines_get(void)
int flag = VCLASS_LIGHT_AREA_SHAPE;
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 2; b++) {
- float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
+ const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
float x = p[(a + b) % 4][0];
float y = p[(a + b) % 4][1];
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x * 0.5f, y * 0.5f, 0.0f}, flag});
@@ -2659,7 +2659,7 @@ GPUBatch *DRW_cache_camera_frame_get(void)
GPU_vertbuf_data_alloc(vbo, v_len);
int v = 0;
- float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
+ const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
/* Frame */
for (int a = 0; a < 4; a++) {
for (int b = 0; b < 2; b++) {
@@ -2740,7 +2740,7 @@ GPUBatch *DRW_cache_camera_tria_wire_get(void)
GPU_vertbuf_data_alloc(vbo, v_len);
int v = 0;
- float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}};
+ const float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}};
for (int a = 0; a < 3; a++) {
for (int b = 0; b < 2; b++) {
float x = p[(a + b) % 3][0];
@@ -2909,9 +2909,8 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
@@ -2947,9 +2946,8 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
@@ -2961,11 +2959,10 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- /* TODO */
- UNUSED_VARS(cu);
- return NULL;
- }
+
+ /* TODO */
+ UNUSED_VARS(cu);
+ return NULL;
}
GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
@@ -2977,9 +2974,8 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -2990,9 +2986,8 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
/* Return list of batches */
@@ -3007,9 +3002,8 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3061,12 +3055,11 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
if (!has_surface) {
return NULL;
}
- else if (mesh_eval != NULL) {
+ if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_surface_get(Object *ob)
@@ -3080,9 +3073,8 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -3096,9 +3088,8 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
@@ -3112,9 +3103,8 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
@@ -3128,9 +3118,8 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
@@ -3146,9 +3135,8 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3166,9 +3154,8 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_triangles_with_normals(cu);
- }
+
+ return DRW_curve_batch_cache_get_triangles_with_normals(cu);
}
GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
@@ -3180,9 +3167,8 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wire_edge(cu);
- }
+
+ return DRW_curve_batch_cache_get_wire_edge(cu);
}
GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
@@ -3194,9 +3180,8 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
}
- else {
- return DRW_curve_batch_cache_get_wireframes_face(cu);
- }
+
+ return DRW_curve_batch_cache_get_wireframes_face(cu);
}
GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
@@ -3207,9 +3192,8 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
}
- else {
- return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
- }
+
+ return DRW_curve_batch_cache_get_edge_detection(cu, r_is_manifold);
}
GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
@@ -3221,11 +3205,10 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
}
- else {
- /* TODO */
- UNUSED_VARS(cu);
- return NULL;
- }
+
+ /* TODO */
+ UNUSED_VARS(cu);
+ return NULL;
}
/* Return list of batches */
@@ -3240,9 +3223,8 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob,
if (mesh_eval != NULL) {
return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
}
- else {
- return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
- }
+
+ return DRW_curve_batch_cache_get_surface_shaded(cu, gpumat_array, gpumat_array_len);
}
/** \} */
@@ -3434,8 +3416,8 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
const int vert_len = segments + 8;
const int index_len = vert_len + 5;
- uchar red[3] = {255, 0, 0};
- uchar white[3] = {255, 255, 255};
+ const uchar red[3] = {255, 0, 0};
+ const uchar white[3] = {255, 255, 255};
static GPUVertFormat format = {0};
static struct {
diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c
index cca8ebcf2a8..a22d4cc95a2 100644
--- a/source/blender/draw/intern/draw_cache_extract_mesh.c
+++ b/source/blender/draw/intern/draw_cache_extract_mesh.c
@@ -474,10 +474,9 @@ BLI_INLINE const float *bm_vert_co_get(const MeshRenderData *mr, const BMVert *e
if (vert_coords != NULL) {
return vert_coords[BM_elem_index_get(eve)];
}
- else {
- UNUSED_VARS(mr);
- return eve->co;
- }
+
+ UNUSED_VARS(mr);
+ return eve->co;
}
BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *eve)
@@ -486,10 +485,9 @@ BLI_INLINE const float *bm_vert_no_get(const MeshRenderData *mr, const BMVert *e
if (vert_normals != NULL) {
return vert_normals[BM_elem_index_get(eve)];
}
- else {
- UNUSED_VARS(mr);
- return eve->no;
- }
+
+ UNUSED_VARS(mr);
+ return eve->no;
}
BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *efa)
@@ -498,10 +496,9 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e
if (poly_normals != NULL) {
return poly_normals[BM_elem_index_get(efa)];
}
- else {
- UNUSED_VARS(mr);
- return efa->no;
- }
+
+ UNUSED_VARS(mr);
+ return efa->no;
}
/** \} */
@@ -2937,7 +2934,7 @@ static float evaluate_vertex_weight(const MDeformVert *dvert, const DRW_MeshWeig
if ((wstate->defgroup_active < 0) && (wstate->defgroup_len > 0)) {
return -2.0f;
}
- else if (dvert == NULL) {
+ if (dvert == NULL) {
return (wstate->alert_mode != OB_DRAW_GROUPUSER_NONE) ? -1.0f : 0.0f;
}
@@ -3614,12 +3611,14 @@ static void compute_normalize_edge_vectors(float auv[2][2],
normalize_v3(av[1]);
}
-static short v2_to_short_angle(float v[2])
+static short v2_to_short_angle(const float v[2])
{
return atan2f(v[1], v[0]) * (float)M_1_PI * SHRT_MAX;
}
-static void edituv_get_stretch_angle(float auv[2][2], float av[2][3], UVStretchAngle *r_stretch)
+static void edituv_get_stretch_angle(float auv[2][2],
+ const float av[2][3],
+ UVStretchAngle *r_stretch)
{
/* Send UV's to the shader and let it compute the aspect corrected angle. */
r_stretch->uv_angles[0] = v2_to_short_angle(auv[0]);
@@ -4296,7 +4295,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
/* non-manifold edge, yet... */
continue;
}
- else if (*pval != NULL) {
+ if (*pval != NULL) {
const float *f1_no = mr->poly_normals[mp_index];
const float *f2_no = *pval;
angle = angle_normalized_v3v3(f1_no, f2_no);
diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.c b/source/blender/draw/intern/draw_cache_impl_gpencil.c
index e8355c1d8da..0ab14574fa6 100644
--- a/source/blender/draw/intern/draw_cache_impl_gpencil.c
+++ b/source/blender/draw/intern/draw_cache_impl_gpencil.c
@@ -135,9 +135,8 @@ static GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
gpencil_batch_cache_clear(cache);
return gpencil_batch_cache_init(ob, cfra);
}
- else {
- return cache;
- }
+
+ return cache;
}
void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
index 66a67d6b8fe..0f80b5159a7 100644
--- a/source/blender/draw/intern/draw_cache_impl_lattice.c
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -83,10 +83,9 @@ static int lattice_render_verts_len_get(Lattice *lt)
if ((lt->flag & LT_OUTSIDE) == 0) {
return vert_len_calc(u, v, w);
}
- else {
- /* TODO remove internal coords */
- return vert_len_calc(u, v, w);
- }
+
+ /* TODO remove internal coords */
+ return vert_len_calc(u, v, w);
}
static int lattice_render_edges_len_get(Lattice *lt)
@@ -102,10 +101,9 @@ static int lattice_render_edges_len_get(Lattice *lt)
if ((lt->flag & LT_OUTSIDE) == 0) {
return edge_len_calc(u, v, w);
}
- else {
- /* TODO remove internal coords */
- return edge_len_calc(u, v, w);
- }
+
+ /* TODO remove internal coords */
+ return edge_len_calc(u, v, w);
}
/* ---------------------------------------------------------------------- */
@@ -252,12 +250,11 @@ static bool lattice_batch_cache_valid(Lattice *lt)
if (cache->is_dirty) {
return false;
}
- else {
- if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) ||
- (cache->dims.w_len != lt->pntsw) ||
- ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) {
- return false;
- }
+
+ if ((cache->dims.u_len != lt->pntsu) || (cache->dims.v_len != lt->pntsv) ||
+ (cache->dims.w_len != lt->pntsw) ||
+ ((cache->show_only_outside != ((lt->flag & LT_OUTSIDE) != 0)))) {
+ return false;
}
return true;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 361c66eca6e..d6faeb16583 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -803,9 +803,8 @@ GPUBatch *DRW_mesh_batch_cache_get_loose_edges(Mesh *me)
if (cache->no_loose_wire) {
return NULL;
}
- else {
- return DRW_batch_request(&cache->batch.loose_edges);
- }
+
+ return DRW_batch_request(&cache->batch.loose_edges);
}
GPUBatch *DRW_mesh_batch_cache_get_surface_weights(Mesh *me)
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index 331a1f80bec..3ecdbff1e96 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -128,9 +128,8 @@ static bool particle_batch_cache_valid(ParticleSystem *psys)
if (cache->is_dirty == false) {
return true;
}
- else {
- return false;
- }
+
+ return false;
return true;
}
@@ -647,14 +646,13 @@ static float particle_key_weight(const ParticleData *particle, int strand, float
if (t == 1.0) {
return hkeys[part->totkey - 1].weight;
}
- else {
- float interp = t / edit_key_seg_t;
- int index = (int)interp;
- interp -= floorf(interp); /* Time between 2 edit key */
- float s1 = hkeys[index].weight;
- float s2 = hkeys[index + 1].weight;
- return s1 + interp * (s2 - s1);
- }
+
+ float interp = t / edit_key_seg_t;
+ int index = (int)interp;
+ interp -= floorf(interp); /* Time between 2 edit key */
+ float s1 = hkeys[index].weight;
+ float s2 = hkeys[index + 1].weight;
+ return s1 + interp * (s2 - s1);
}
static int particle_batch_cache_fill_segments_edit(
diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.c b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
index 17902f27513..06cedb9f72c 100644
--- a/source/blender/draw/intern/draw_cache_impl_pointcloud.c
+++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.c
@@ -158,6 +158,7 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
const bool has_radius = pointcloud->radius != NULL;
static GPUVertFormat format = {0};
+ static GPUVertFormat format_no_radius = {0};
static uint pos;
if (format.attr_len == 0) {
/* initialize vertex format */
@@ -167,11 +168,11 @@ static void pointcloud_batch_cache_ensure_pos(Object *ob, PointCloudBatchCache *
* If the vertex shader has more components than the array provides, the extras are given
* values from the vector (0, 0, 0, 1) for the missing XYZW components.
*/
- int comp_len = has_radius ? 4 : 3;
- pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, comp_len, GPU_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(&format_no_radius, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
}
- cache->pos = GPU_vertbuf_create_with_format(&format);
+ cache->pos = GPU_vertbuf_create_with_format(has_radius ? &format : &format_no_radius);
GPU_vertbuf_data_alloc(cache->pos, pointcloud->totpoint);
if (has_radius) {
diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c
index 095e928aa74..f0d73d5bb84 100644
--- a/source/blender/draw/intern/draw_common.c
+++ b/source/blender/draw/intern/draw_common.c
@@ -455,11 +455,11 @@ bool DRW_object_is_flat(Object *ob, int *r_axis)
*r_axis = 0;
return true;
}
- else if (dim[1] == 0.0f) {
+ if (dim[1] == 0.0f) {
*r_axis = 1;
return true;
}
- else if (dim[2] == 0.0f) {
+ if (dim[2] == 0.0f) {
*r_axis = 2;
return true;
}
@@ -489,7 +489,7 @@ static void DRW_evaluate_weight_to_color(const float weight, float result[4])
* increasing widens yellow/cyan vs red/green/blue.
* Gamma 1.0 produces the original 2.79 color ramp. */
const float gamma = 1.5f;
- float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)};
+ const float hsv[3] = {(2.0f / 3.0f) * (1.0f - weight), 1.0f, pow(0.5f + 0.5f * weight, gamma)};
hsv_to_rgb_v(hsv, result);
diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h
index d7bb9b78e09..6060dce47ac 100644
--- a/source/blender/draw/intern/draw_common.h
+++ b/source/blender/draw/intern/draw_common.h
@@ -26,8 +26,10 @@ struct DRWPass;
struct DRWShadingGroup;
struct GPUMaterial;
struct ModifierData;
+struct FluidModifierData;
struct Object;
struct ParticleSystem;
+struct RegionView3D;
struct ViewLayer;
#define UBO_FIRST_COLOR colorWire
@@ -158,14 +160,14 @@ void DRW_globals_update(void);
void DRW_globals_free(void);
struct DRWView *DRW_view_create_with_zoffset(const struct DRWView *parent_view,
- const RegionView3D *rv3d,
+ const struct RegionView3D *rv3d,
float offset);
int DRW_object_wire_theme_get(struct Object *ob, struct ViewLayer *view_layer, float **r_color);
float *DRW_color_background_blend_get(int theme_id);
-bool DRW_object_is_flat(Object *ob, int *r_axis);
-bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis);
+bool DRW_object_is_flat(struct Object *ob, int *r_axis);
+bool DRW_object_axis_orthogonal_to_view(struct Object *ob, int axis);
/* draw_hair.c */
@@ -187,6 +189,16 @@ void DRW_hair_init(void);
void DRW_hair_update(void);
void DRW_hair_free(void);
+/* draw_fluid.c */
+
+/* Fluid simulation. */
+void DRW_smoke_ensure(struct FluidModifierData *fmd, int highres);
+void DRW_smoke_ensure_coba_field(struct FluidModifierData *fmd);
+void DRW_smoke_ensure_velocity(struct FluidModifierData *fmd);
+
+void DRW_smoke_free(struct FluidModifierData *fmd);
+void DRW_smoke_free_velocity(struct FluidModifierData *fmd);
+
/* draw_common.c */
struct DRW_Global {
/** If needed, contains all global/Theme colors
diff --git a/source/blender/gpu/intern/gpu_draw_smoke.c b/source/blender/draw/intern/draw_fluid.c
index e0b94e20574..33311dc698f 100644
--- a/source/blender/gpu/intern/gpu_draw_smoke.c
+++ b/source/blender/draw/intern/draw_fluid.c
@@ -35,10 +35,10 @@
#include "BKE_colorband.h"
-#include "GPU_draw.h"
-#include "GPU_glew.h"
#include "GPU_texture.h"
+#include "draw_common.h" /* Own include. */
+
#ifdef WITH_FLUID
# include "manta_fluid_API.h"
#endif
@@ -62,7 +62,8 @@ static void create_flame_spectrum_texture(float *data)
# define MAX_FIRE_ALPHA 0.06f
# define FULL_ON_FIRE 100
- float *spec_pixels = MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float), "spec_pixels");
+ float *spec_pixels = (float *)MEM_mallocN(TFUNC_WIDTH * 4 * 16 * 16 * sizeof(float),
+ "spec_pixels");
blackbody_temperature_to_rgb_table(data, TFUNC_WIDTH, 1500, 3000);
@@ -105,7 +106,7 @@ static void create_color_ramp(const struct ColorBand *coba, float *data)
static GPUTexture *create_transfer_function(int type, const struct ColorBand *coba)
{
- float *data = MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__);
+ float *data = (float *)MEM_mallocN(sizeof(float) * 4 * TFUNC_WIDTH, __func__);
switch (type) {
case TFUNC_FLAME_SPECTRUM:
@@ -184,7 +185,7 @@ static GPUTexture *create_field_texture(FluidDomainSettings *fds)
}
GPUTexture *tex = GPU_texture_create_nD(
- fds->res[0], fds->res[1], fds->res[2], 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
+ UNPACK3(fds->res), 3, field, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
swizzle_texture_channel_single(tex);
return tex;
@@ -203,7 +204,7 @@ static GPUTexture *create_density_texture(FluidDomainSettings *fds, int highres)
}
GPUTexture *tex = GPU_texture_create_nD(
- dim[0], dim[1], dim[2], 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
+ UNPACK3(dim), 3, data, GPU_R8, GPU_DATA_FLOAT, 0, true, NULL);
swizzle_texture_channel_single(tex);
@@ -221,7 +222,7 @@ static GPUTexture *create_color_texture(FluidDomainSettings *fds, int highres)
int cell_count = (highres) ? manta_noise_get_cells(fds->fluid) : fds->total_cells;
int *dim = (highres) ? fds->res_noise : fds->res;
- float *data = MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
+ float *data = (float *)MEM_callocN(sizeof(float) * cell_count * 4, "smokeColorTexture");
if (data == NULL) {
return NULL;
@@ -276,7 +277,7 @@ static GPUTexture *create_flame_texture(FluidDomainSettings *fds, int highres)
/** \name Public API
* \{ */
-void GPU_free_smoke(FluidModifierData *fmd)
+void DRW_smoke_free(FluidModifierData *fmd)
{
if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
if (fmd->domain->tex_density) {
@@ -316,7 +317,7 @@ void GPU_free_smoke(FluidModifierData *fmd)
}
}
-void GPU_create_smoke_coba_field(FluidModifierData *fmd)
+void DRW_smoke_ensure_coba_field(FluidModifierData *fmd)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd);
@@ -334,7 +335,7 @@ void GPU_create_smoke_coba_field(FluidModifierData *fmd)
#endif
}
-void GPU_create_smoke(FluidModifierData *fmd, int highres)
+void DRW_smoke_ensure(FluidModifierData *fmd, int highres)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd, highres);
@@ -355,9 +356,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres)
fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL);
}
if (!fds->tex_shadow) {
- fds->tex_shadow = GPU_texture_create_nD(fds->res[0],
- fds->res[1],
- fds->res[2],
+ fds->tex_shadow = GPU_texture_create_nD(UNPACK3(fds->res),
3,
manta_smoke_get_shadow(fds->fluid),
GPU_R8,
@@ -370,7 +369,7 @@ void GPU_create_smoke(FluidModifierData *fmd, int highres)
#endif /* WITH_FLUID */
}
-void GPU_create_smoke_velocity(FluidModifierData *fmd)
+void DRW_smoke_ensure_velocity(FluidModifierData *fmd)
{
#ifndef WITH_FLUID
UNUSED_VARS(fmd);
@@ -387,19 +386,16 @@ void GPU_create_smoke_velocity(FluidModifierData *fmd)
}
if (!fds->tex_velocity_x) {
- fds->tex_velocity_x = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_x, NULL);
- fds->tex_velocity_y = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_y, NULL);
- fds->tex_velocity_z = GPU_texture_create_3d(
- fds->res[0], fds->res[1], fds->res[2], GPU_R16F, vel_z, NULL);
+ fds->tex_velocity_x = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_x, NULL);
+ fds->tex_velocity_y = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_y, NULL);
+ fds->tex_velocity_z = GPU_texture_create_3d(UNPACK3(fds->res), GPU_R16F, vel_z, NULL);
}
}
#endif /* WITH_FLUID */
}
-/* TODO Unify with the other GPU_free_smoke. */
-void GPU_free_smoke_velocity(FluidModifierData *fmd)
+/* TODO Unify with the other DRW_smoke_free. */
+void DRW_smoke_free_velocity(FluidModifierData *fmd)
{
if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) {
if (fmd->domain->tex_velocity_x) {
diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c
index cbdcbbf9090..1cbf3ee9d54 100644
--- a/source/blender/draw/intern/draw_hair.c
+++ b/source/blender/draw/intern/draw_hair.c
@@ -114,7 +114,7 @@ void DRW_hair_init(void)
g_dummy_vbo = GPU_vertbuf_create_with_format(&format);
- float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPU_vertbuf_data_alloc(g_dummy_vbo, 1);
GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert);
/* Create vbo immediately to bind to texture buffer. */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 2beab021cfb..4a5e07476a9 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -792,9 +792,8 @@ DrawDataList *DRW_drawdatalist_from_id(ID *id)
IdDdtTemplate *idt = (IdDdtTemplate *)id;
return &idt->drawdata;
}
- else {
- return NULL;
- }
+
+ return NULL;
}
DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type)
@@ -2031,7 +2030,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
}
}
- int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
+ const int viewport_size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)};
struct GPUViewport *viewport = GPU_viewport_create();
GPU_viewport_size_set(viewport, viewport_size);
@@ -2723,7 +2722,7 @@ void DRW_engines_free(void)
void DRW_render_context_enable(Render *render)
{
if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
+ WM_init_opengl();
}
if (GPU_use_main_context_workaround()) {
@@ -2854,7 +2853,7 @@ void DRW_opengl_context_disable_ex(bool restore)
void DRW_opengl_context_enable(void)
{
if (G.background && DST.gl_context == NULL) {
- WM_init_opengl(G_MAIN);
+ WM_init_opengl();
}
DRW_opengl_context_enable_ex(true);
}
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 9d8050504ab..661a27c10b7 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -594,28 +594,26 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup,
DRWResourceHandle handle = 0;
return handle;
}
- else {
- return drw_resource_handle_new(obmat, NULL);
- }
+
+ return drw_resource_handle_new(obmat, NULL);
+ }
+
+ if (DST.ob_handle == 0) {
+ DST.ob_handle = drw_resource_handle_new(obmat, ob);
+ DST.ob_state_obinfo_init = false;
}
- else {
- if (DST.ob_handle == 0) {
- DST.ob_handle = drw_resource_handle_new(obmat, ob);
- DST.ob_state_obinfo_init = false;
- }
- if (shgroup->objectinfo) {
- if (!DST.ob_state_obinfo_init) {
- DST.ob_state_obinfo_init = true;
- DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
- &DST.ob_handle);
+ if (shgroup->objectinfo) {
+ if (!DST.ob_state_obinfo_init) {
+ DST.ob_state_obinfo_init = true;
+ DRWObjectInfos *ob_infos = DRW_memblock_elem_from_handle(DST.vmempool->obinfos,
+ &DST.ob_handle);
- drw_call_obinfos_init(ob_infos, ob);
- }
+ drw_call_obinfos_init(ob_infos, ob);
}
-
- return DST.ob_handle;
}
+
+ return DST.ob_handle;
}
static void command_type_set(uint64_t *command_type_bits, int index, eDRWCommandType type)
@@ -1292,13 +1290,10 @@ static DRWShadingGroup *drw_shgroup_material_create_ex(GPUPass *gpupass, DRWPass
}
static void drw_shgroup_material_texture(DRWShadingGroup *grp,
- GPUMaterialTexture *tex,
+ GPUTexture *gputex,
const char *name,
- eGPUSamplerState state,
- int textarget)
+ eGPUSamplerState state)
{
- GPUTexture *gputex = GPU_texture_from_blender(tex->ima, tex->iuser, NULL, textarget);
-
DRW_shgroup_uniform_texture_ex(grp, name, gputex, state);
GPUTexture **gputex_ref = BLI_memblock_alloc(DST.vmempool->images);
@@ -1314,15 +1309,16 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial
LISTBASE_FOREACH (GPUMaterialTexture *, tex, &textures) {
if (tex->ima) {
/* Image */
+ GPUTexture *gputex;
if (tex->tiled_mapping_name[0]) {
- drw_shgroup_material_texture(
- grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D_ARRAY);
- drw_shgroup_material_texture(
- grp, tex, tex->tiled_mapping_name, tex->sampler_state, GL_TEXTURE_1D_ARRAY);
+ gputex = BKE_image_get_gpu_tiles(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
+ gputex = BKE_image_get_gpu_tilemap(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state);
}
else {
- drw_shgroup_material_texture(
- grp, tex, tex->sampler_name, tex->sampler_state, GL_TEXTURE_2D);
+ gputex = BKE_image_get_gpu_texture(tex->ima, tex->iuser, NULL);
+ drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
}
}
else if (tex->colorband) {
@@ -1906,9 +1902,8 @@ float DRW_view_near_distance_get(const DRWView *view)
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] - 1.0f);
}
- else {
- return -(projmat[3][2] + 1.0f) / projmat[2][2];
- }
+
+ return -(projmat[3][2] + 1.0f) / projmat[2][2];
}
float DRW_view_far_distance_get(const DRWView *view)
@@ -1919,9 +1914,8 @@ float DRW_view_far_distance_get(const DRWView *view)
if (DRW_view_is_persp_get(view)) {
return -projmat[3][2] / (projmat[2][2] + 1.0f);
}
- else {
- return -(projmat[3][2] - 1.0f) / projmat[2][2];
- }
+
+ return -(projmat[3][2] - 1.0f) / projmat[2][2];
}
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse)
@@ -2028,18 +2022,16 @@ static int pass_shgroup_dist_sort(const void *a, const void *b)
if (shgrp_a->z_sorting.distance < shgrp_b->z_sorting.distance) {
return 1;
}
- else if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) {
+ if (shgrp_a->z_sorting.distance > shgrp_b->z_sorting.distance) {
return -1;
}
- else {
- /* If distances are the same, keep original order. */
- if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) {
- return -1;
- }
- else {
- return 0;
- }
+
+ /* If distances are the same, keep original order. */
+ if (shgrp_a->z_sorting.original_index > shgrp_b->z_sorting.original_index) {
+ return -1;
}
+
+ return 0;
}
/* ------------------ Shading group sorting --------------------- */
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c
index b6f51ada5a1..4b63ea89e44 100644
--- a/source/blender/draw/intern/draw_manager_exec.c
+++ b/source/blender/draw/intern/draw_manager_exec.c
@@ -446,6 +446,7 @@ void DRW_state_reset(void)
DRW_state_reset_ex(DRW_STATE_DEFAULT);
GPU_texture_unbind_all();
+ GPU_uniformbuffer_unbind_all();
/* Should stay constant during the whole rendering. */
GPU_point_size(5);
@@ -517,7 +518,7 @@ static bool draw_culling_box_test(const float (*frustum_planes)[4], const BoundB
* Go to next plane. */
break;
}
- else if (v == 7) {
+ if (v == 7) {
/* 8 points behind this plane. */
return false;
}
@@ -669,8 +670,7 @@ BLI_INLINE void draw_geometry_bind(DRWShadingGroup *shgroup, GPUBatch *geom)
DST.batch = geom;
- GPU_batch_program_set_no_use(
- geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
+ GPU_batch_set_shader_no_bind(geom, shgroup->shader);
geom->program_in_use = true; /* XXX hacking #GPUBatch */
@@ -773,10 +773,11 @@ static bool ubo_bindings_validate(DRWShadingGroup *shgroup)
DRWPass *parent_pass = DRW_memblock_elem_from_handle(DST.vmempool->passes,
&shgroup->pass_handle);
- printf("Pass : %s, Shader : %s, Block : %s\n",
+ printf("Pass : %s, Shader : %s, Block : %s, Binding %d\n",
parent_pass->name,
shgroup->shader->name,
- blockname);
+ blockname,
+ binding);
}
}
# endif
@@ -994,9 +995,8 @@ static void draw_call_single_do(DRWShadingGroup *shgroup,
draw_select_buffer(shgroup, state, batch, &handle);
return;
}
- else {
- GPU_select_load_id(state->select_id);
- }
+
+ GPU_select_load_id(state->select_id);
}
draw_geometry_execute(shgroup,
@@ -1106,6 +1106,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
/* Unbinding can be costly. Skip in normal condition. */
if (G.debug & G_DEBUG_GPU) {
GPU_texture_unbind_all();
+ GPU_uniformbuffer_unbind_all();
}
}
GPU_shader_bind(shgroup->shader);
diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c
index 34069438e47..1c260721efb 100644
--- a/source/blender/draw/intern/draw_manager_shader.c
+++ b/source/blender/draw/intern/draw_manager_shader.c
@@ -447,7 +447,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred)
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render() || !deferred) {
@@ -467,7 +468,8 @@ GPUMaterial *DRW_shader_create_from_world(struct Scene *scene,
geom,
frag_lib,
defines,
- wo->id.name);
+ wo->id.name,
+ callback);
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
@@ -487,7 +489,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
const char *geom,
const char *frag_lib,
const char *defines,
- bool deferred)
+ bool deferred,
+ GPUMaterialEvalCallbackFn callback)
{
GPUMaterial *mat = NULL;
if (DRW_state_is_image_render() || !deferred) {
@@ -507,7 +510,8 @@ GPUMaterial *DRW_shader_create_from_material(struct Scene *scene,
geom,
frag_lib,
defines,
- ma->id.name);
+ ma->id.name,
+ callback);
}
if (GPU_material_status(mat) == GPU_MAT_QUEUED) {
diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c
index 84c8d0f861f..ee5561e1e38 100644
--- a/source/blender/draw/intern/draw_select_buffer.c
+++ b/source/blender/draw/intern/draw_select_buffer.c
@@ -395,7 +395,7 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
int center_x = width / 2;
int center_y = height / 2;
- /* Manhatten distance in keeping with other screen-based selection. */
+ /* Manhattan distance in keeping with other screen-based selection. */
*dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
/* Indices start at 1 here. */
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 3c470f802ec..1458ff5341c 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -88,7 +88,7 @@ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, Vie
/* no exception met? then don't draw cursor! */
return false;
}
- else if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) {
+ if (draw_ctx->object_mode & OB_MODE_WEIGHT_GPENCIL) {
/* grease pencil hide always in some modes */
return false;
}
@@ -184,8 +184,7 @@ void DRW_draw_cursor(void)
GPUBatch *cursor_batch = DRW_cache_cursor_get(is_aligned);
GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_FLAT_COLOR);
- GPU_batch_program_set(
- cursor_batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
+ GPU_batch_set_shader(cursor_batch, shader);
GPU_batch_draw(cursor_batch);
diff --git a/source/blender/draw/intern/shaders/common_hair_lib.glsl b/source/blender/draw/intern/shaders/common_hair_lib.glsl
index ffff631e34b..8684d82f228 100644
--- a/source/blender/draw/intern/shaders/common_hair_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_hair_lib.glsl
@@ -95,7 +95,7 @@ void hair_get_interp_attrs(
* For final drawing, the vertex index and the number of vertex per segment
*/
-#ifndef HAIR_PHASE_SUBDIV
+#if !defined(HAIR_PHASE_SUBDIV) && defined(GPU_VERTEX_SHADER)
int hair_get_strand_id(void)
{
return gl_VertexID / (hairStrandsRes * hairThicknessRes);
@@ -206,4 +206,24 @@ vec3 hair_get_strand_pos(void)
return texelFetch(hairPointBuffer, id).point_position;
}
+vec2 hair_get_barycentric(void)
+{
+ /* To match cycles without breaking into individual segment we encode if we need to invert
+ * the first component into the second component. We invert if the barycentricTexCo.y
+ * is NOT 0.0 or 1.0. */
+ int id = hair_get_base_id();
+ return vec2(float((id % 2) == 1), float(((id % 4) % 3) > 0));
+}
+
#endif
+
+/* To be fed the result of hair_get_barycentric from vertex shader. */
+vec2 hair_resolve_barycentric(vec2 vert_barycentric)
+{
+ if (fract(vert_barycentric.y) != 0.0) {
+ return vec2(vert_barycentric.x, 0.0);
+ }
+ else {
+ return vec2(1.0 - vert_barycentric.x, 0.0);
+ }
+}
diff --git a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
index e337376d7c4..643d7e7d942 100644
--- a/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_math_geom_lib.glsl
@@ -116,4 +116,4 @@ vec3 normal_decode(vec2 enc, vec3 view)
return n;
}
-/** \} */ \ No newline at end of file
+/** \} */
diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
index 36b67f2bd60..625e8bb1ff8 100644
--- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl
@@ -36,4 +36,4 @@ vec3 pointcloud_get_pos(void)
vec3 outpos, outnor;
pointcloud_get_pos_and_nor(outpos, outnor);
return outpos;
-} \ No newline at end of file
+}
diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl
index 095bc64a19e..a55d2cd8c1a 100644
--- a/source/blender/draw/intern/shaders/common_view_lib.glsl
+++ b/source/blender/draw/intern/shaders/common_view_lib.glsl
@@ -22,6 +22,16 @@ layout(std140) uniform viewBlock
vec4 CameraTexCoFactors;
};
+#define ViewNear (ViewVecs[0].w)
+#define ViewFar (ViewVecs[1].w)
+
+#define cameraForward ViewMatrixInverse[2].xyz
+#define cameraPos ViewMatrixInverse[3].xyz
+#define cameraVec \
+ ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
+#define viewCameraVec \
+ ((ProjectionMatrix[3][3] == 0.0) ? normalize(-viewPosition) : vec3(0.0, 0.0, 1.0))
+
#ifdef world_clip_planes_calc_clip_distance
# undef world_clip_planes_calc_clip_distance
# define world_clip_planes_calc_clip_distance(p) \
@@ -104,10 +114,13 @@ uniform int resourceId;
/* Use this to declare and pass the value if
* the fragment shader uses the resource_id. */
-# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
-# define RESOURCE_ID_VARYING_GEOM flat out int resourceIDGeom;
-# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
-# define PASS_RESOURCE_ID_GEOM resourceIDGeom = resource_id;
+# ifdef USE_GEOMETRY_SHADER
+# define RESOURCE_ID_VARYING flat out int resourceIDGeom;
+# define PASS_RESOURCE_ID resourceIDGeom = resource_id;
+# else
+# define RESOURCE_ID_VARYING flat out int resourceIDFrag;
+# define PASS_RESOURCE_ID resourceIDFrag = resource_id;
+# endif
#endif
/* If used in a fragment / geometry shader, we pass
@@ -118,7 +131,7 @@ uniform int resourceId;
flat in int resourceIDGeom[];
# define resource_id resourceIDGeom
-# define PASS_RESOURCE_ID(i) resourceIDFrag = resource_id[i];
+# define PASS_RESOURCE_ID resourceIDFrag = resource_id[0];
#endif
#ifdef GPU_FRAGMENT_SHADER
@@ -171,9 +184,12 @@ uniform mat4 ModelMatrixInverse;
* Note: This is only valid because we are only using the mat3 of the ViewMatrixInverse.
* ViewMatrix * transpose(ModelMatrixInverse)
**/
-#define normal_object_to_view(n) (mat3(ViewMatrix) * (transpose(mat3(ModelMatrixInverse)) * n))
-#define normal_object_to_world(n) (transpose(mat3(ModelMatrixInverse)) * n)
-#define normal_world_to_object(n) (transpose(mat3(ModelMatrix)) * n)
+#define NormalMatrix transpose(mat3(ModelMatrixInverse))
+#define NormalMatrixInverse transpose(mat3(ModelMatrix))
+
+#define normal_object_to_view(n) (mat3(ViewMatrix) * (NormalMatrix * n))
+#define normal_object_to_world(n) (NormalMatrix * n)
+#define normal_world_to_object(n) (NormalMatrixInverse * n)
#define normal_world_to_view(n) (mat3(ViewMatrix) * n)
#define normal_view_to_world(n) (mat3(ViewMatrixInverse) * n)
@@ -199,3 +215,78 @@ uniform mat4 ModelMatrixInverse;
#define DRW_BASE_FROM_DUPLI (1 << 2)
#define DRW_BASE_FROM_SET (1 << 3)
#define DRW_BASE_ACTIVE (1 << 4)
+
+/* ---- Opengl Depth conversion ---- */
+
+float linear_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zn * zf) / (z * (zn - zf) + zf);
+ }
+ else {
+ return (z * 2.0 - 1.0) * zf;
+ }
+}
+
+float buffer_depth(bool is_persp, float z, float zf, float zn)
+{
+ if (is_persp) {
+ return (zf * (zn - z)) / (z * (zn - zf));
+ }
+ else {
+ return (z / (zf * 2.0)) + 0.5;
+ }
+}
+
+float get_view_z_from_depth(float depth)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ float d = 2.0 * depth - 1.0;
+ return -ProjectionMatrix[3][2] / (d + ProjectionMatrix[2][2]);
+ }
+ else {
+ return ViewVecs[0].z + depth * ViewVecs[1].z;
+ }
+}
+
+float get_depth_from_view_z(float z)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ float d = (-ProjectionMatrix[3][2] / z) - ProjectionMatrix[2][2];
+ return d * 0.5 + 0.5;
+ }
+ else {
+ return (z - ViewVecs[0].z) / ViewVecs[1].z;
+ }
+}
+
+vec2 get_uvs_from_view(vec3 view)
+{
+ vec4 ndc = ProjectionMatrix * vec4(view, 1.0);
+ return (ndc.xy / ndc.w) * 0.5 + 0.5;
+}
+
+vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return vec3(ViewVecs[0].xy + uvcoords * ViewVecs[1].xy, 1.0) * get_view_z_from_depth(depth);
+ }
+ else {
+ return ViewVecs[0].xyz + vec3(uvcoords, depth) * ViewVecs[1].xyz;
+ }
+}
+
+vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
+{
+ return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
+}
+
+vec3 get_view_vector_from_screen_uv(vec2 uv)
+{
+ if (ProjectionMatrix[3][3] == 0.0) {
+ return normalize(vec3(ViewVecs[0].xy + uv * ViewVecs[1].xy, 1.0));
+ }
+ else {
+ return vec3(0.0, 0.0, 1.0);
+ }
+}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 50733afe6fb..8280b58c21a 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -427,7 +427,7 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
ac->spacetype = (area) ? area->spacetype : 0;
ac->regiontype = (region) ? region->regiontype : 0;
- /* initialise default y-scale factor */
+ /* Initialize default y-scale factor. */
animedit_get_yscale_factor(ac);
/* get data context info */
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 8df9c99896e..e60270bc3f0 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -251,7 +251,7 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
*/
BLI_dlrbTree_init(&pso->keys);
- /* initialise numeric input */
+ /* Initialize numeric input. */
initNumInput(&pso->num);
pso->num.idx_max = 0; /* one axis */
pso->num.val_flag[0] |= NUM_NO_NEGATIVE;
@@ -1310,7 +1310,7 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
pso = op->customdata;
- /* initialise percentage so that it won't pop on first mouse move */
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1370,7 +1370,7 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
pso = op->customdata;
- /* initialise percentage so that it won't pop on first mouse move */
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1429,7 +1429,7 @@ static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEven
pso = op->customdata;
- /* initialise percentage so that it won't pop on first mouse move */
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1489,7 +1489,7 @@ static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEve
pso = op->customdata;
- /* initialise percentage so that it won't pop on first mouse move */
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
@@ -1549,7 +1549,7 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
pso = op->customdata;
- /* initialise percentage so that it won't pop on first mouse move */
+ /* Initialize percentage so that it won't pop on first mouse move. */
pose_slide_mouse_update_percentage(pso, op, event);
/* do common setup work */
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 91a8ea0fa3a..69a05c9ae31 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1137,7 +1137,7 @@ int ED_curve_updateAnimPaths(Main *bmain, Curve *cu)
/** \name Edit Mode Conversion (Make & Load)
* \{ */
-static int *initialize_index_map(Object *obedit, int *r_old_totvert)
+static int *init_index_map(Object *obedit, int *r_old_totvert)
{
Curve *curve = (Curve *)obedit->data;
EditNurb *editnurb = curve->editnurb;
@@ -1225,7 +1225,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
if ((object->parent) && (object->parent->data == curve) &&
ELEM(object->partype, PARVERT1, PARVERT3)) {
if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ old_to_new_map = init_index_map(obedit, &old_totvert);
}
if (object->par1 < old_totvert) {
@@ -1254,7 +1254,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit)
int i, j;
if (old_to_new_map == NULL) {
- old_to_new_map = initialize_index_map(obedit, &old_totvert);
+ old_to_new_map = init_index_map(obedit, &old_totvert);
}
for (i = j = 0; i < hmd->totindex; i++) {
@@ -1716,7 +1716,10 @@ static bool isNurbselV(Nurb *nu, int *u, int flag)
return 1;
}
-static void rotateflagNurb(ListBase *editnurb, short flag, const float cent[3], float rotmat[3][3])
+static void rotateflagNurb(ListBase *editnurb,
+ short flag,
+ const float cent[3],
+ const float rotmat[3][3])
{
/* all verts with (flag & 'flag') rotate */
Nurb *nu;
diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c
index bacdd5b69b5..75d90df3291 100644
--- a/source/blender/editors/curve/editcurve_add.c
+++ b/source/blender/editors/curve/editcurve_add.c
@@ -397,8 +397,8 @@ Nurb *ED_curve_add_nurbs_primitive(
break;
case CU_PRIM_SPHERE: /* sphere */
if (cutype == CU_NURBS) {
- float tmp_cent[3] = {0.f, 0.f, 0.f};
- float tmp_vec[3] = {0.f, 0.f, 1.f};
+ const float tmp_cent[3] = {0.f, 0.f, 0.f};
+ const float tmp_vec[3] = {0.f, 0.f, 1.f};
nu->pntsu = 5;
nu->pntsv = 1;
@@ -451,8 +451,8 @@ Nurb *ED_curve_add_nurbs_primitive(
break;
case CU_PRIM_DONUT: /* torus */
if (cutype == CU_NURBS) {
- float tmp_cent[3] = {0.f, 0.f, 0.f};
- float tmp_vec[3] = {0.f, 0.f, 1.f};
+ const float tmp_cent[3] = {0.f, 0.f, 0.f};
+ const float tmp_vec[3] = {0.f, 0.f, 1.f};
xzproj = 1;
nu = ED_curve_add_nurbs_primitive(C, obedit, mat, CU_NURBS | CU_PRIM_CIRCLE, 0);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index b759277572c..4529209b297 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -76,9 +76,9 @@ static int kill_selection(Object *obedit, int ins);
/** \name Internal Utilities
* \{ */
-static wchar_t findaccent(wchar_t char1, uint code)
+static char32_t findaccent(char32_t char1, uint code)
{
- wchar_t new = 0;
+ char32_t new = 0;
if (char1 == 'a') {
if (code == '`') {
@@ -648,7 +648,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
int nchars = 0, nbytes = 0;
char *s;
int a;
- float rot[3] = {0.f, 0.f, 0.f};
+ const float rot[3] = {0.f, 0.f, 0.f};
obedit = BKE_object_add(bmain, scene, view_layer, OB_FONT, NULL);
base = view_layer->basact;
@@ -682,7 +682,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo");
cu->len = 0;
- cu->len_wchar = nchars - 1;
+ cu->len_char32 = nchars - 1;
cu->pos = 0;
s = cu->str;
@@ -703,7 +703,7 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const
}
}
- cu->pos = cu->len_wchar;
+ cu->pos = cu->len_char32;
*s = '\0';
WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit);
@@ -1661,7 +1661,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
uintptr_t ascii = event->ascii;
int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
int event_type = event->type, event_val = event->val;
- wchar_t inserted_text[2] = {0};
+ char32_t inserted_text[2] = {0};
if (RNA_struct_property_is_set(op->ptr, "text")) {
return insert_text_exec(C, op);
@@ -1733,7 +1733,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* store as utf8 in RNA string */
char inserted_utf8[8] = {0};
- BLI_strncpy_wchar_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
+ BLI_str_utf32_as_utf8(inserted_utf8, inserted_text, sizeof(inserted_utf8));
RNA_string_set(op->ptr, "text", inserted_utf8);
}
@@ -1867,7 +1867,7 @@ void ED_curve_editfont_make(Object *obedit)
{
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
- int len_wchar;
+ int len_char32;
if (ef == NULL) {
ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
@@ -1876,10 +1876,10 @@ void ED_curve_editfont_make(Object *obedit)
ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
}
- /* Convert the original text to wchar_t */
- len_wchar = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
- BLI_assert(len_wchar == cu->len_wchar);
- ef->len = len_wchar;
+ /* Convert the original text to chat32_t. */
+ len_char32 = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
+ BLI_assert(len_char32 == cu->len_char32);
+ ef->len = len_char32;
BLI_assert(ef->len >= 0);
memcpy(ef->textbufinfo, cu->strinfo, ef->len * sizeof(CharInfo));
@@ -1908,7 +1908,7 @@ void ED_curve_editfont_load(Object *obedit)
MEM_freeN(cu->str);
/* Calculate the actual string length in UTF-8 variable characters */
- cu->len_wchar = ef->len;
+ cu->len_char32 = ef->len;
cu->len = BLI_str_utf32_as_utf8_len(ef->textbuf);
/* Alloc memory for UTF-8 variable char length string */
@@ -1920,8 +1920,8 @@ void ED_curve_editfont_load(Object *obedit)
if (cu->strinfo) {
MEM_freeN(cu->strinfo);
}
- cu->strinfo = MEM_callocN((cu->len_wchar + 4) * sizeof(CharInfo), "texteditinfo");
- memcpy(cu->strinfo, ef->textbufinfo, cu->len_wchar * sizeof(CharInfo));
+ cu->strinfo = MEM_callocN((cu->len_char32 + 4) * sizeof(CharInfo), "texteditinfo");
+ memcpy(cu->strinfo, ef->textbufinfo, cu->len_char32 * sizeof(CharInfo));
/* Other vars */
cu->pos = ef->pos;
diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
index 71a364c60d7..033673a99a8 100644
--- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c
+++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c
@@ -29,7 +29,6 @@
#include "ED_view3d.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
index f31e004264c..341f43d0662 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c
@@ -239,7 +239,7 @@ static int gizmo_arrow_test_select(bContext *UNUSED(C), wmGizmo *gz, const int m
WM_gizmo_calc_matrix_final(gz, matrix_final);
/* Arrow in pixel space. */
- float arrow_start[2] = {matrix_final[3][0], matrix_final[3][1]};
+ const float arrow_start[2] = {matrix_final[3][0], matrix_final[3][1]};
float arrow_end[2];
{
float co[3] = {0, 0, arrow_length};
diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
index 04b93f35681..c5231b3cd96 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c
@@ -99,7 +99,7 @@ static void button2d_geom_draw_backdrop(const wmGizmo *gz,
else {
/* Draw fill. */
if ((fill_alpha != 0.0f) || (select == true)) {
- float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]};
+ const float fill_color[4] = {UNPACK3(color), fill_alpha * color[3]};
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(fill_color);
imm_draw_circle_fill_2d(pos, 0, 0, 1.0f, CIRCLE_RESOLUTION);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
index 85f84af5f14..406d66dfd8f 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c
@@ -999,7 +999,7 @@ static int gizmo_cage2d_modal(bContext *C,
if (data->dial == NULL) {
MUL_V2_V3_M4_FINAL(test_co, data->orig_matrix_offset[3]);
- data->dial = BLI_dial_initialize(test_co, FLT_EPSILON);
+ data->dial = BLI_dial_init(test_co, FLT_EPSILON);
MUL_V2_V3_M4_FINAL(test_co, data->orig_mouse);
BLI_dial_angle(data->dial, test_co);
diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
index 8955a666e22..0bc65fe10a5 100644
--- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
+++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c
@@ -257,7 +257,7 @@ static void cage3d_draw_circle_handles(const RegionView3D *rv3d,
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor3fv(color);
- float sign[3] = {-1.0f, 0.0f, 1.0f};
+ const float sign[3] = {-1.0f, 0.0f, 1.0f};
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
for (int z = 0; z < 3; z++) {
diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c
index 6f700f6c4b8..30e4fe0b531 100644
--- a/source/blender/editors/gpencil/annotate_paint.c
+++ b/source/blender/editors/gpencil/annotate_paint.c
@@ -200,7 +200,7 @@ typedef struct tGPsdata {
/* Macros for accessing sensitivity thresholds... */
/* minimum number of pixels mouse should move before new point created */
-#define MIN_MANHATTEN_PX (U.gp_manhattendist)
+#define MIN_MANHATTAN_PX (U.gp_manhattandist)
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
@@ -271,7 +271,7 @@ static void annotation_get_3d_reference(tGPsdata *p, float vec[3])
/* Stroke Editing ---------------------------- */
/* check if the current mouse position is suitable for adding a new point */
-static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float pmval[2])
+static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], const float pmval[2])
{
int dx = (int)fabsf(mval[0] - pmval[0]);
int dy = (int)fabsf(mval[1] - pmval[1]);
@@ -297,7 +297,7 @@ static bool annotation_stroke_filtermval(tGPsdata *p, const float mval[2], float
return false;
}
- if ((dx > MIN_MANHATTEN_PX) && (dy > MIN_MANHATTEN_PX)) {
+ if ((dx > MIN_MANHATTAN_PX) && (dy > MIN_MANHATTAN_PX)) {
return true;
}
@@ -573,14 +573,14 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* Arrow end corner. */
if (gpd->runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_END) {
pt++;
- float e_heading[2] = {start[0] - end[0], start[1] - end[1]};
+ const float e_heading[2] = {start[0] - end[0], start[1] - end[1]};
/* Calculate points for ending arrow. */
annotation_stroke_arrow_calc_points(
pt, e_heading, end, gpd->runtime.arrow_end, gpd->runtime.arrow_end_style);
}
/* Arrow start corner. */
if (gpd->runtime.sbuffer_sflag & GP_STROKE_USE_ARROW_START) {
- float s_heading[2] = {end[0] - start[0], end[1] - start[1]};
+ const float s_heading[2] = {end[0] - start[0], end[1] - start[1]};
/* Calculate points for starting arrow. */
annotation_stroke_arrow_calc_points(
NULL, s_heading, start, gpd->runtime.arrow_start, gpd->runtime.arrow_start_style);
@@ -603,7 +603,7 @@ static short annotation_stroke_addpoint(tGPsdata *p,
/* store settings */
copy_v2_v2(&pt->x, mval);
pt->pressure = pressure;
- /* unused for annotations, but initialise for easier conversions to GP Object */
+ /* Unused for annotations, but initialize for easier conversions to GP Object. */
pt->strength = 1.0f;
/* point time */
@@ -704,7 +704,7 @@ static void annotation_stroke_arrow_init_point(
tGPsdata *p, tGPspoint *ptc, bGPDspoint *pt, const float co[8], const int co_idx)
{
/* Note: provided co_idx should be always pair number as it's [x1, y1, x2, y2, x3, y3]. */
- float real_co[2] = {co[co_idx], co[co_idx + 1]};
+ const float real_co[2] = {co[co_idx], co[co_idx + 1]};
copy_v2_v2(&ptc->x, real_co);
annotation_stroke_convertcoords(p, &ptc->x, &pt->x, NULL);
annotation_stroke_arrow_init_point_default(pt);
diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c
index 96b0296a7de..348fb614977 100644
--- a/source/blender/editors/gpencil/gpencil_data.c
+++ b/source/blender/editors/gpencil/gpencil_data.c
@@ -861,6 +861,154 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot)
INT_MAX);
}
+/* ********************* Clean Duplicated Frames ************************** */
+static bool gpencil_frame_is_equal(bGPDframe *gpf_a, bGPDframe *gpf_b)
+{
+ if ((gpf_a == NULL) || (gpf_b == NULL)) {
+ return false;
+ }
+ /* If the number of strokes is different, cannot be equal. */
+ int totstrokes_a = BLI_listbase_count(&gpf_a->strokes);
+ int totstrokes_b = BLI_listbase_count(&gpf_b->strokes);
+ if ((totstrokes_a == 0) || (totstrokes_b == 0) || (totstrokes_a != totstrokes_b)) {
+ return false;
+ }
+ /* Loop all strokes and check. */
+ bGPDstroke *gps_a = gpf_a->strokes.first;
+ bGPDstroke *gps_b = gpf_b->strokes.first;
+ for (int i = 0; i < totstrokes_a; i++) {
+ /* If the number of points is different, cannot be equal. */
+ if (gps_a->totpoints != gps_b->totpoints) {
+ return false;
+ }
+ /* Check other variables. */
+ if (!equals_v4v4(gps_a->vert_color_fill, gps_b->vert_color_fill)) {
+ return false;
+ }
+ if (gps_a->thickness != gps_b->thickness) {
+ return false;
+ }
+ if (gps_a->mat_nr != gps_b->mat_nr) {
+ return false;
+ }
+ if (gps_a->caps[0] != gps_b->caps[0]) {
+ return false;
+ }
+ if (gps_a->caps[1] != gps_b->caps[1]) {
+ return false;
+ }
+ if (gps_a->hardeness != gps_b->hardeness) {
+ return false;
+ }
+ if (!equals_v2v2(gps_a->aspect_ratio, gps_b->aspect_ratio)) {
+ return false;
+ }
+ if (gps_a->uv_rotation != gps_b->uv_rotation) {
+ return false;
+ }
+ if (!equals_v2v2(gps_a->uv_translation, gps_b->uv_translation)) {
+ return false;
+ }
+ if (gps_a->uv_scale != gps_b->uv_scale) {
+ return false;
+ }
+
+ /* Loop points and check if equals or not. */
+ for (int p = 0; p < gps_a->totpoints; p++) {
+ bGPDspoint *pt_a = &gps_a->points[p];
+ bGPDspoint *pt_b = &gps_b->points[p];
+ if (!equals_v3v3(&pt_a->x, &pt_b->x)) {
+ return false;
+ }
+ if (pt_a->pressure != pt_b->pressure) {
+ return false;
+ }
+ if (pt_a->strength != pt_b->strength) {
+ return false;
+ }
+ if (pt_a->uv_fac != pt_b->uv_fac) {
+ return false;
+ }
+ if (pt_a->uv_rot != pt_b->uv_rot) {
+ return false;
+ }
+ if (!equals_v4v4(pt_a->vert_color, pt_b->vert_color)) {
+ return false;
+ }
+ }
+
+ /* Look at next pair of strokes. */
+ gps_a = gps_a->next;
+ gps_b = gps_b->next;
+ }
+
+ return true;
+}
+
+static int gpencil_frame_clean_duplicate_exec(bContext *C, wmOperator *op)
+{
+#define SELECTED 1
+
+ bool changed = false;
+ Object *ob = CTX_data_active_object(C);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const int type = RNA_enum_get(op->ptr, "type");
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ /* Only editable and visible layers are considered. */
+ if (BKE_gpencil_layer_is_editable(gpl) && (gpl->frames.first != NULL)) {
+ bGPDframe *gpf = gpl->frames.first;
+
+ if ((type == SELECTED) && ((gpf->flag & GP_FRAME_SELECT) == 0)) {
+ continue;
+ }
+
+ while (gpf != NULL) {
+ if (gpencil_frame_is_equal(gpf, gpf->next)) {
+ /* Remove frame. */
+ BKE_gpencil_layer_frame_delete(gpl, gpf->next);
+ /* Tag for recalc. */
+ changed = true;
+ }
+ else {
+ gpf = gpf->next;
+ }
+ }
+ }
+ }
+
+ /* notifiers */
+ if (changed) {
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void GPENCIL_OT_frame_clean_duplicate(wmOperatorType *ot)
+{
+ static const EnumPropertyItem clean_type[] = {
+ {0, "ALL", 0, "All Frames", ""},
+ {1, "SELECTED", 0, "Selected Frames", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ /* identifiers */
+ ot->name = "Clean Duplicated Frames";
+ ot->idname = "GPENCIL_OT_frame_clean_duplicate";
+ ot->description = "Remove any duplicated frame";
+
+ /* callbacks */
+ ot->exec = gpencil_frame_clean_duplicate_exec;
+ ot->poll = gpencil_active_layer_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ ot->prop = RNA_def_enum(ot->srna, "type", clean_type, 0, "Type", "");
+}
+
/* *********************** Hide Layers ******************************** */
static int gpencil_hide_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 286efeeff01..99e98df3397 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -94,6 +94,8 @@
/** \name Stroke Edit Mode Management
* \{ */
+static void gpencil_flip_stroke(bGPDstroke *gps);
+
/* poll callback for all stroke editing operators */
static bool gpencil_stroke_edit_poll(bContext *C)
{
@@ -1126,6 +1128,11 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps)
pt->flag |= GP_SPOINT_SELECT;
}
+ /* Flip stroke if it was only one point to consider extrude point as last point. */
+ if (gps->totpoints == 2) {
+ gpencil_flip_stroke(gps);
+ }
+
/* Calc geometry data. */
BKE_gpencil_stroke_geometry_update(gps);
@@ -1764,7 +1771,7 @@ static int gpencil_blank_frame_add_exec(bContext *C, wmOperator *op)
const bool all_layers = RNA_boolean_get(op->ptr, "all_layers");
- /* Initialise datablock and an active layer if nothing exists yet */
+ /* Initialize data-block and an active layer if nothing exists yet. */
if (ELEM(NULL, gpd, active_gpl)) {
/* Let's just be lazy, and call the "Add New Layer" operator,
* which sets everything up as required. */
@@ -3369,7 +3376,7 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a,
bGPDspoint point;
bGPDspoint *pt;
int i;
- float delta[3] = {1.0f, 1.0f, 1.0f};
+ const float delta[3] = {1.0f, 1.0f, 1.0f};
float deltatime = 0.0f;
/* sanity checks */
@@ -4283,14 +4290,14 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
base_new = ED_object_add_duplicate(bmain, scene, view_layer, base_prev, dupflag);
ob_dst = base_new->object;
ob_dst->mode = OB_MODE_OBJECT;
- /* Duplication will increment bGPdata usercount, but since we create a new greasepencil datablock
- * for ob_dst (which gets its own user automatically), we have to decrement the usercount again.
- */
+ /* Duplication will increment #bGPdata user-count, but since we create a new grease-pencil
+ * data-block for ob_dst (which gets its own user automatically),
+ * we have to decrement the user-count again. */
gpd_dst = BKE_gpencil_data_addnew(bmain, gpd_src->id.name + 2);
id_us_min(ob_dst->data);
ob_dst->data = (bGPdata *)gpd_dst;
- /* loop old datablock and separate parts */
+ /* Loop old data-block and separate parts. */
if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) {
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
gpl_dst = NULL;
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 517225e5a81..a70bbfc9d48 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -104,6 +104,8 @@ typedef struct tGPDfill {
struct bGPdata *gpd;
/** current material */
struct Material *mat;
+ /** current brush */
+ struct Brush *brush;
/** layer */
struct bGPDlayer *gpl;
/** frame */
@@ -233,6 +235,8 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
Object *ob = tgpf->ob;
bGPdata *gpd = tgpf->gpd;
+ Brush *brush = tgpf->brush;
+ BrushGpencilSettings *brush_settings = brush->gpencil_settings;
tGPDdraw tgpw;
tgpw.rv3d = tgpf->rv3d;
@@ -249,6 +253,12 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
GPU_blend(true);
+ bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd);
+ BLI_assert(gpl_active != NULL);
+
+ const int gpl_active_index = BLI_findindex(&gpd->layers, gpl_active);
+ BLI_assert(gpl_active_index >= 0);
+
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
/* calculate parent position */
BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
@@ -258,6 +268,44 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
continue;
}
+ /* Decide if layer is included or not depending of the layer mode. */
+ const int gpl_index = BLI_findindex(&gpd->layers, gpl);
+ switch (brush_settings->fill_layer_mode) {
+ case GP_FILL_GPLMODE_ACTIVE: {
+ if (gpl_index != gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ABOVE: {
+ if (gpl_index != gpl_active_index + 1) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_BELOW: {
+ if (gpl_index != gpl_active_index - 1) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_ABOVE: {
+ if (gpl_index <= gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_ALL_BELOW: {
+ if (gpl_index >= gpl_active_index) {
+ continue;
+ }
+ break;
+ }
+ case GP_FILL_GPLMODE_VISIBLE:
+ default:
+ break;
+ }
+
/* if active layer and no keyframe, create a new one */
if (gpl == tgpf->gpl) {
if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) {
@@ -408,7 +456,7 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
GPU_matrix_set(tgpf->rv3d->viewmat);
/* draw strokes */
- float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f};
+ const float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f};
gpencil_draw_datablock(tgpf, ink);
GPU_matrix_pop_projection();
@@ -416,10 +464,10 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf)
/* create a image to see result of template */
if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(offscreen, GL_FLOAT, ibuf->rect_float);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_FLOAT, ibuf->rect_float);
}
else if (ibuf->rect) {
- GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, ibuf->rect);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, ibuf->rect);
}
if (ibuf->rect_float && ibuf->rect) {
IMB_rect_from_float(ibuf);
@@ -1247,6 +1295,7 @@ static tGPDfill *gpencil_session_init_fill(bContext *C, wmOperator *UNUSED(op))
/* save filling parameters */
Brush *brush = BKE_paint_brush(&ts->gp_paint->paint);
+ tgpf->brush = brush;
tgpf->flag = brush->gpencil_settings->flag;
tgpf->fill_leak = brush->gpencil_settings->fill_leak;
tgpf->fill_threshold = brush->gpencil_settings->fill_threshold;
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 66ac7948596..fa75c2a7cee 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -484,6 +484,7 @@ void GPENCIL_OT_active_frames_delete_all(struct wmOperatorType *ot);
void GPENCIL_OT_frame_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_fill(struct wmOperatorType *ot);
void GPENCIL_OT_frame_clean_loose(struct wmOperatorType *ot);
+void GPENCIL_OT_frame_clean_duplicate(struct wmOperatorType *ot);
void GPENCIL_OT_convert(struct wmOperatorType *ot);
void GPENCIL_OT_bake_mesh_animation(struct wmOperatorType *ot);
diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c
index 11f42f7d3ac..a6088e31ff8 100644
--- a/source/blender/editors/gpencil/gpencil_mesh.c
+++ b/source/blender/editors/gpencil/gpencil_mesh.c
@@ -196,7 +196,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op)
bool newob = false;
if (STREQ(target, "*NEW")) {
ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0;
- float loc[3] = {0.0f, 0.0f, 0.0f};
+ const float loc[3] = {0.0f, 0.0f, 0.0f};
ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits);
newob = true;
}
diff --git a/source/blender/editors/gpencil/gpencil_ops.c b/source/blender/editors/gpencil/gpencil_ops.c
index efee05f7da3..3892f451e18 100644
--- a/source/blender/editors/gpencil/gpencil_ops.c
+++ b/source/blender/editors/gpencil/gpencil_ops.c
@@ -600,6 +600,7 @@ void ED_operatortypes_gpencil(void)
WM_operatortype_append(GPENCIL_OT_frame_duplicate);
WM_operatortype_append(GPENCIL_OT_frame_clean_fill);
WM_operatortype_append(GPENCIL_OT_frame_clean_loose);
+ WM_operatortype_append(GPENCIL_OT_frame_clean_duplicate);
WM_operatortype_append(GPENCIL_OT_convert);
WM_operatortype_append(GPENCIL_OT_bake_mesh_animation);
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 1880045e238..611fe158948 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -268,7 +268,7 @@ typedef struct tGPsdata {
/* Macros for accessing sensitivity thresholds... */
/* minimum number of pixels mouse should move before new point created */
-#define MIN_MANHATTEN_PX (U.gp_manhattendist)
+#define MIN_MANHATTEN_PX (U.gp_manhattandist)
/* minimum length of new segment before new point can be added */
#define MIN_EUCLIDEAN_PX (U.gp_euclideandist)
@@ -362,7 +362,7 @@ static void gpencil_get_3d_reference(tGPsdata *p, float vec[3])
/* Stroke Editing ---------------------------- */
/* check if the current mouse position is suitable for adding a new point */
-static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], float mvalo[2])
+static bool gpencil_stroke_filtermval(tGPsdata *p, const float mval[2], const float mvalo[2])
{
Brush *brush = p->brush;
int dx = (int)fabsf(mval[0] - mvalo[0]);
@@ -519,7 +519,7 @@ static void gpencil_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const
/* default angle of brush in radians */
float angle = brush->gpencil_settings->draw_angle;
/* angle vector of the brush with full thickness */
- float v0[2] = {cos(angle), sin(angle)};
+ const float v0[2] = {cos(angle), sin(angle)};
/* Apply to first point (only if there are 2 points because before no data to do it ) */
if (gpd->runtime.sbuffer_used == 1) {
@@ -1817,15 +1817,15 @@ static void gpencil_init_drawing_brush(bContext *C, tGPsdata *p)
changed = true;
}
/* Be sure curves are initializated. */
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_sensitivity);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_strength);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_jitter);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_pressure);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_strength);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_uv);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_hue);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_saturation);
- BKE_curvemapping_initialize(paint->brush->gpencil_settings->curve_rand_value);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_sensitivity);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_strength);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_jitter);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_pressure);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_strength);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_uv);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_hue);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_saturation);
+ BKE_curvemapping_init(paint->brush->gpencil_settings->curve_rand_value);
/* assign to temp tGPsdata */
p->brush = paint->brush;
@@ -3247,7 +3247,7 @@ static void gpencil_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoi
float fac;
/* angle vector of the brush with full thickness */
- float v0[2] = {cos(angle), sin(angle)};
+ const float v0[2] = {cos(angle), sin(angle)};
mvec[0] = pt->x - pt_prev->x;
mvec[1] = pt->y - pt_prev->y;
@@ -3269,7 +3269,7 @@ static void gpencil_brush_angle_segment(tGPsdata *p, tGPspoint *pt_prev, tGPspoi
* + PtA - 1
* /
* CTL is the vertice of the triangle created between PtA and PtB */
-static void gpencil_add_arc_points(tGPsdata *p, float mval[2], int segments)
+static void gpencil_add_arc_points(tGPsdata *p, const float mval[2], int segments)
{
bGPdata *gpd = p->gpd;
BrushGpencilSettings *brush_settings = p->brush->gpencil_settings;
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 20f959e2e2c..28ea9535a80 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -378,7 +378,10 @@ static void gpencil_primitive_add_segment(tGPDprimitive *tgpi)
}
/* Helper: set control point */
-static void gpencil_primitive_set_cp(tGPDprimitive *tgpi, float p[2], float color[4], int size)
+static void gpencil_primitive_set_cp(tGPDprimitive *tgpi,
+ const float p[2],
+ float color[4],
+ int size)
{
if (tgpi->flag == IN_PROGRESS) {
return;
@@ -696,7 +699,6 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
bool is_depth = (bool)(*align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE));
const bool is_camera = (bool)(ts->gp_sculpt.lock_axis == 0) &&
(tgpi->rv3d->persp == RV3D_CAMOB) && (!is_depth);
- const bool is_vertex_stroke = GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush);
if (tgpi->type == GP_STROKE_BOX) {
gps->totpoints = (tgpi->tot_edges * 4 + tgpi->tot_stored_edges);
@@ -742,13 +744,13 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
gpencil_session_validatebuffer(tgpi);
gpencil_init_colors(tgpi);
if (gset->flag & GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_primitive);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_primitive);
}
if (brush_settings->flag & GP_BRUSH_USE_JITTER_PRESSURE) {
- BKE_curvemapping_initialize(brush_settings->curve_jitter);
+ BKE_curvemapping_init(brush_settings->curve_jitter);
}
if (brush_settings->flag & GP_BRUSH_USE_STRENGTH_PRESSURE) {
- BKE_curvemapping_initialize(brush_settings->curve_strength);
+ BKE_curvemapping_init(brush_settings->curve_strength);
}
/* get an array of depths, far depths are blended */
@@ -1021,12 +1023,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
pt->time = 0.0f;
pt->flag = 0;
pt->uv_fac = tpt->uv_fac;
- if (is_vertex_stroke) {
- copy_v4_v4(pt->vert_color, tpt->vert_color);
- }
- else {
- zero_v4(pt->vert_color);
- }
+ ED_gpencil_point_vertex_color_set(ts, brush, pt, tpt);
if (gps->dvert != NULL) {
MDeformVert *dvert = &gps->dvert[i];
@@ -1092,7 +1089,7 @@ static void gpencil_primitive_update(bContext *C, wmOperator *op, tGPDprimitive
gpencil_primitive_update_strokes(C, tgpi);
}
-/* Initialise mouse points */
+/* Initialize mouse points. */
static void gpencil_primitive_interaction_begin(tGPDprimitive *tgpi, const wmEvent *event)
{
copy_v2fl_v2i(tgpi->mval, event->mval);
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 20eeab65623..43c8b766c52 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -444,7 +444,9 @@ typedef struct tGPSB_Grab_StrokeData {
int size;
} tGPSB_Grab_StrokeData;
-/* initialise custom data for handling this stroke */
+/**
+ * Initialize custom data for handling this stroke.
+ */
static void gpencil_brush_grab_stroke_init(tGP_BrushEditData *gso, bGPDstroke *gps)
{
tGPSB_Grab_StrokeData *data = NULL;
@@ -910,13 +912,13 @@ typedef struct tGPSB_CloneBrushData {
GHash *new_colors;
} tGPSB_CloneBrushData;
-/* Initialise "clone" brush data */
+/* Initialize "clone" brush data. */
static void gpencil_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
{
tGPSB_CloneBrushData *data;
bGPDstroke *gps;
- /* init custom data */
+ /* Initialize custom-data. */
gso->customdata = data = MEM_callocN(sizeof(tGPSB_CloneBrushData), "CloneBrushData");
/* compute midpoint of strokes on clipboard */
@@ -1188,7 +1190,7 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
Paint *paint = &ts->gp_sculptpaint->paint;
gso->brush = paint->brush;
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
/* save mask */
gso->mask = ts->gpencil_selectmode_sculpt;
@@ -1200,10 +1202,10 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
- /* initialise custom data for brushes */
+ /* Initialize custom data for brushes. */
char tool = gso->brush->gpencil_sculpt_tool;
switch (tool) {
case GPSCULPT_TOOL_CLONE: {
@@ -1229,13 +1231,13 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
op->customdata = NULL;
return false;
}
- /* initialise customdata */
+ /* Initialize custom-data. */
gpencil_brush_clone_init(C, gso);
break;
}
case GPSCULPT_TOOL_GRAB: {
- /* initialise the cache needed for this brush */
+ /* Initialize the cache needed for this brush. */
gso->stroke_customdata = BLI_ghash_ptr_new("GP Grab Brush - Strokes Hash");
break;
}
@@ -1936,7 +1938,7 @@ static int gpencil_sculpt_brush_invoke(bContext *C, wmOperator *op, const wmEven
gso = op->customdata;
- /* initialise type-specific data (used for the entire session) */
+ /* Initialize type-specific data (used for the entire session). */
char tool = gso->brush->gpencil_sculpt_tool;
switch (tool) {
/* Brushes requiring timer... */
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index f77bb394567..aaf88e1a0b0 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -1080,7 +1080,7 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
}
}
else {
- float scale[3] = {1.0f, 1.0f, 1.0f};
+ const float scale[3] = {1.0f, 1.0f, 1.0f};
plane_normal[2] = 1.0f;
float mat[4][4];
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
@@ -1285,7 +1285,7 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
}
}
else {
- float scale[3] = {1.0f, 1.0f, 1.0f};
+ const float scale[3] = {1.0f, 1.0f, 1.0f};
plane_normal[2] = 1.0f;
float mat[4][4];
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
@@ -1469,7 +1469,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
/* Helper function to create new OB_GPENCIL Object */
Object *ED_gpencil_add_object(bContext *C, const float loc[3], ushort local_view_bits)
{
- float rot[3] = {0.0f};
+ const float rot[3] = {0.0f};
Object *ob = ED_object_add_type(C, OB_GPENCIL, NULL, loc, rot, false, local_view_bits);
@@ -1500,7 +1500,7 @@ void ED_gpencil_add_defaults(bContext *C, Object *ob)
if (ts->gp_sculpt.cur_falloff == NULL) {
ts->gp_sculpt.cur_falloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
CurveMapping *gp_falloff_curve = ts->gp_sculpt.cur_falloff;
- BKE_curvemapping_initialize(gp_falloff_curve);
+ BKE_curvemapping_init(gp_falloff_curve);
BKE_curvemap_reset(gp_falloff_curve->cm,
&gp_falloff_curve->clipr,
CURVE_PRESET_GAUSS,
@@ -1723,7 +1723,7 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
/* Cursor drawing */
/* check if cursor is in drawing region */
-static bool gpencil_check_cursor_region(bContext *C, int mval_i[2])
+static bool gpencil_check_cursor_region(bContext *C, const int mval_i[2])
{
ARegion *region = CTX_wm_region(C);
ScrArea *area = CTX_wm_area(C);
@@ -2311,7 +2311,9 @@ static void gpencil_insert_point(
MEM_SAFE_FREE(temp_points);
}
-static float gpencil_calc_factor(float p2d_a1[2], float p2d_a2[2], float r_hit2d[2])
+static float gpencil_calc_factor(const float p2d_a1[2],
+ const float p2d_a2[2],
+ const float r_hit2d[2])
{
float dist1 = len_squared_v2v2(p2d_a1, p2d_a2);
float dist2 = len_squared_v2v2(p2d_a1, r_hit2d);
@@ -2688,7 +2690,11 @@ void ED_gpencil_tag_scene_gpencil(Scene *scene)
void ED_gpencil_fill_vertex_color_set(ToolSettings *ts, Brush *brush, bGPDstroke *gps)
{
- if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) {
+ const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+ if (is_vertex) {
copy_v3_v3(gps->vert_color_fill, brush->rgb);
gps->vert_color_fill[3] = brush->gpencil_settings->vertex_factor;
srgb_to_linearrgb_v4(gps->vert_color_fill, gps->vert_color_fill);
@@ -2703,7 +2709,12 @@ void ED_gpencil_point_vertex_color_set(ToolSettings *ts,
bGPDspoint *pt,
tGPspoint *tpt)
{
- if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) {
+ const bool is_vertex = (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
+ if (is_vertex) {
if (tpt == NULL) {
copy_v3_v3(pt->vert_color, brush->rgb);
pt->vert_color[3] = brush->gpencil_settings->vertex_factor;
@@ -2859,6 +2870,18 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
bGPdata *gpd_eval = (bGPdata *)ob_eval->data;
MaterialGPencilStyle *gp_style = material->gp_style;
+ const bool is_vertex_fill =
+ (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
+ const bool is_vertex_stroke =
+ (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) ||
+ (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) &&
+ (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR));
+
int idx = gpd->runtime.sbuffer_used;
tGPspoint *tpt = (tGPspoint *)gpd->runtime.sbuffer + idx;
@@ -2868,14 +2891,14 @@ void ED_gpencil_sbuffer_vertex_color_set(Depsgraph *depsgraph,
srgb_to_linearrgb_v4(vertex_color, vertex_color);
/* Copy fill vertex color. */
- if (GPENCIL_USE_VERTEX_COLOR_FILL(ts, brush)) {
+ if (is_vertex_fill) {
copy_v4_v4(gpd->runtime.vert_color_fill, vertex_color);
}
else {
copy_v4_v4(gpd->runtime.vert_color_fill, gp_style->fill_rgba);
}
/* Copy stroke vertex color. */
- if (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush)) {
+ if (is_vertex_stroke) {
copy_v4_v4(tpt->vert_color, vertex_color);
}
else {
diff --git a/source/blender/editors/gpencil/gpencil_vertex_paint.c b/source/blender/editors/gpencil/gpencil_vertex_paint.c
index c36bc4388d7..b0dff6589da 100644
--- a/source/blender/editors/gpencil/gpencil_vertex_paint.c
+++ b/source/blender/editors/gpencil/gpencil_vertex_paint.c
@@ -727,7 +727,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op)
gso->brush = paint->brush;
srgb_to_linearrgb_v3_v3(gso->linear_color, gso->brush->rgb);
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
gso->is_painting = false;
gso->first = true;
@@ -759,7 +759,7 @@ static bool gpencil_vertexpaint_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* Setup space conversions. */
diff --git a/source/blender/editors/gpencil/gpencil_weight_paint.c b/source/blender/editors/gpencil/gpencil_weight_paint.c
index 4392ec92824..9d3e9c6ae45 100644
--- a/source/blender/editors/gpencil/gpencil_weight_paint.c
+++ b/source/blender/editors/gpencil/gpencil_weight_paint.c
@@ -295,7 +295,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
gso->bmain = CTX_data_main(C);
gso->brush = paint->brush;
- BKE_curvemapping_initialize(gso->brush->curve);
+ BKE_curvemapping_init(gso->brush->curve);
gso->is_painting = false;
gso->first = true;
@@ -326,7 +326,7 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
/* Init multi-edit falloff curve data before doing anything,
* so we won't have to do it again later. */
if (gso->is_multiframe) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* Setup space conversions. */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index e0ce72e5c3c..1d688b2ad68 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -23,6 +23,8 @@
#pragma once
+#include "GPU_texture.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -65,21 +67,19 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float xzoom,
float yzoom,
- float color[4]);
+ const float color[4]);
void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float x,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float clip_min_x,
float clip_min_y,
@@ -87,29 +87,27 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float clip_max_y,
float xzoom,
float yzoom,
- float color[4]);
+ const float color[4]);
void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
float x,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
float xzoom,
float yzoom,
- float color[4]);
+ const float color[4]);
void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float x,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -119,7 +117,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float clip_max_y,
float xzoom,
float yzoom,
- float color[4]);
+ const float color[4]);
/* Image buffer drawing functions, with display transform
*
@@ -132,7 +130,7 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
void ED_draw_imbuf(struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
struct ColorManagedViewSettings *view_settings,
struct ColorManagedDisplaySettings *display_settings,
float zoom_x,
@@ -140,7 +138,7 @@ void ED_draw_imbuf(struct ImBuf *ibuf,
void ED_draw_imbuf_clipping(struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
struct ColorManagedViewSettings *view_settings,
struct ColorManagedDisplaySettings *display_settings,
float clip_min_x,
@@ -154,14 +152,14 @@ void ED_draw_imbuf_ctx(const struct bContext *C,
struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float zoom_x,
float zoom_y);
void ED_draw_imbuf_ctx_clipping(const struct bContext *C,
struct ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float clip_min_x,
float clip_min_y,
float clip_max_x,
diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h
index 8206f5a8619..ccef62eb8d2 100644
--- a/source/blender/editors/include/ED_buttons.h
+++ b/source/blender/editors/include/ED_buttons.h
@@ -26,6 +26,10 @@
extern "C" {
#endif
+struct SpaceProperties;
+
+int ED_buttons_tabs_list(struct SpaceProperties *sbuts, int *context_tabs_array);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 447b7b76c72..6c5aacafc7a 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -102,8 +102,12 @@ bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
-bool user_string_to_number(
- bContext *C, const char *str, const struct UnitSettings *unit, int type, double *r_value);
+bool user_string_to_number(bContext *C,
+ const char *str,
+ const struct UnitSettings *unit,
+ int type,
+ const char *error_prefix,
+ double *r_value);
/** \} */
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 59567803f35..29fe766b2d0 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -72,7 +72,7 @@ void ED_region_exit(struct bContext *C, struct ARegion *region);
void ED_region_remove(struct bContext *C, struct ScrArea *area, struct ARegion *region);
void ED_region_pixelspace(struct ARegion *region);
void ED_region_update_rect(struct ARegion *region);
-void ED_region_floating_initialize(struct ARegion *region);
+void ED_region_floating_init(struct ARegion *region);
void ED_region_tag_redraw(struct ARegion *region);
void ED_region_tag_redraw_partial(struct ARegion *region, const struct rcti *rct, bool rebuild);
void ED_region_tag_redraw_cursor(struct ARegion *region);
@@ -170,7 +170,7 @@ void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco);
/* areas */
-void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
+void ED_area_init(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area);
void ED_area_exit(struct bContext *C, struct ScrArea *area);
int ED_screen_area_active(const struct bContext *C);
void ED_screen_global_areas_refresh(struct wmWindow *win);
@@ -220,7 +220,7 @@ ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area);
vert_name->next)
/* screens */
-void ED_screens_initialize(struct Main *bmain, struct wmWindowManager *wm);
+void ED_screens_init(struct Main *bmain, struct wmWindowManager *wm);
void ED_screen_draw_edges(struct wmWindow *win);
void ED_screen_draw_join_shape(struct ScrArea *sa1, struct ScrArea *sa2);
void ED_screen_draw_split_preview(struct ScrArea *area, const int dir, const float fac);
@@ -286,6 +286,12 @@ bool ED_workspace_delete(struct WorkSpace *workspace,
struct bContext *C,
struct wmWindowManager *wm) ATTR_NONNULL();
void ED_workspace_scene_data_sync(struct WorkSpaceInstanceHook *hook, Scene *scene) ATTR_NONNULL();
+struct WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout(
+ struct Main *bmain,
+ struct WorkSpace *workspace,
+ struct WorkSpaceLayout *layout_new,
+ const struct WorkSpaceLayout *layout_fallback_base,
+ struct wmWindow *win) ATTR_NONNULL();
struct WorkSpaceLayout *ED_workspace_layout_add(struct Main *bmain,
struct WorkSpace *workspace,
struct wmWindow *win,
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 739a2184fb5..ddbea592238 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -698,17 +698,6 @@ float ED_view3d_grid_view_scale(struct Scene *scene,
void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset);
-/* view matrix properties utilities */
-/* unused */
-#if 0
-void ED_view3d_operator_properties_viewmat(struct wmOperatorType *ot);
-void ED_view3d_operator_properties_viewmat_set(struct bContext *C, struct wmOperator *op);
-void ED_view3d_operator_properties_viewmat_get(struct wmOperator *op,
- int *winx,
- int *winy,
- float persmat[4][4]);
-#endif
-
/* render */
void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *region);
void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *area);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index d682597da8e..e8352bc6b21 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -57,6 +57,7 @@ struct bNodeSocket;
struct bNodeTree;
struct bScreen;
struct rcti;
+struct uiButSearch;
struct uiFontStyle;
struct uiList;
struct uiStyle;
@@ -100,7 +101,7 @@ typedef struct uiPopupBlockHandle uiPopupBlockHandle;
/* use for clamping popups within the screen */
#define UI_SCREEN_MARGIN 10
-/* uiBlock->dt and uiBut->dt */
+/** #uiBlock.emboss and #uiBut.emboss */
enum {
UI_EMBOSS = 0, /* use widget style for drawing */
UI_EMBOSS_NONE = 1, /* Nothing, only icon and/or text */
@@ -371,6 +372,7 @@ typedef enum {
UI_BTYPE_SEPR_SPACER = 56 << 9,
/** Resize handle (resize uilist). */
UI_BTYPE_GRIP = 57 << 9,
+ UI_BTYPE_DECORATOR = 58 << 9,
} eButType;
#define BUTTYPE (63 << 9)
@@ -388,8 +390,6 @@ enum {
UI_GRAD_L_ALT = 10,
};
-#define UI_PALETTE_COLOR 20
-
/* Drawing
*
* Functions to draw various shapes, taking theme settings into account.
@@ -500,7 +500,7 @@ typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
/* Search types. */
typedef struct ARegion *(*uiButSearchCreateFn)(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ struct uiButSearch *search_but);
typedef void (*uiButSearchUpdateFn)(const struct bContext *C,
void *arg,
const char *str,
@@ -537,7 +537,7 @@ typedef bool (*uiMenuStepFunc)(struct bContext *C, int direction, void *arg1);
bool UI_but_has_tooltip_label(const uiBut *but);
bool UI_but_is_tool(const uiBut *but);
bool UI_but_is_utf8(const uiBut *but);
-#define UI_but_is_decorator(but) ((but)->func == ui_but_anim_decorate_cb)
+#define UI_but_is_decorator(but) ((but)->type == UI_BTYPE_DECORATOR)
bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title);
bool UI_block_is_empty(const uiBlock *block);
@@ -656,7 +656,7 @@ bool UI_popup_block_name_exists(const struct bScreen *screen, const char *name);
uiBlock *UI_block_begin(const struct bContext *C,
struct ARegion *region,
const char *name,
- short dt);
+ char emboss);
void UI_block_end_ex(const struct bContext *C, uiBlock *block, const int xy[2], int r_xy[2]);
void UI_block_end(const struct bContext *C, uiBlock *block);
void UI_block_draw(const struct bContext *C, struct uiBlock *block);
@@ -670,7 +670,7 @@ enum {
};
void UI_block_theme_style_set(uiBlock *block, char theme_style);
char UI_block_emboss_get(uiBlock *block);
-void UI_block_emboss_set(uiBlock *block, char dt);
+void UI_block_emboss_set(uiBlock *block, char emboss);
void UI_block_free(const struct bContext *C, uiBlock *block);
void UI_blocklist_free(const struct bContext *C, struct ListBase *lb);
@@ -1929,8 +1929,6 @@ uiLayout *uiLayoutGridFlow(uiLayout *layout,
uiLayout *uiLayoutBox(uiLayout *layout);
uiLayout *uiLayoutListBox(uiLayout *layout,
struct uiList *ui_list,
- struct PointerRNA *ptr,
- struct PropertyRNA *prop,
struct PointerRNA *actptr,
struct PropertyRNA *actprop);
uiLayout *uiLayoutAbsolute(uiLayout *layout, bool align);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 286cb1571bd..a84ca33a7d7 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -52,7 +52,6 @@
#include "BKE_screen.h"
#include "BKE_unit.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
@@ -808,7 +807,12 @@ static bool ui_but_update_from_old_block(const bContext *C,
SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons);
- SWAP(struct uiButSearchData *, oldbut->search, but->search);
+ if (oldbut->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but;
+
+ SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn);
+ SWAP(void *, search_oldbut->arg, search_but->arg);
+ }
/* copy hardmin for list rows to prevent 'sticking' highlight to mouse position
* when scrolling without moving mouse (see [#28432]) */
@@ -816,10 +820,10 @@ static bool ui_but_update_from_old_block(const bContext *C,
oldbut->hardmax = but->hardmax;
}
- /* Selectively copy a1, a2 since their use differs across all button types
- * (and we'll probably split these out later) */
- if (ELEM(oldbut->type, UI_BTYPE_PROGRESS_BAR)) {
- oldbut->a1 = but->a1;
+ if (oldbut->type == UI_BTYPE_PROGRESS_BAR) {
+ uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut;
+ uiButProgressbar *progress_but = (uiButProgressbar *)but;
+ progress_oldbut->progress = progress_but->progress;
}
if (!BLI_listbase_is_empty(&block->butstore)) {
@@ -1493,7 +1497,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
continue;
}
}
- else if (but->dt != UI_EMBOSS_PULLDOWN) {
+ else if (but->emboss != UI_EMBOSS_PULLDOWN) {
continue;
}
@@ -1774,7 +1778,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
+ ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
ui_but_predefined_extra_operator_icons_add(but);
}
@@ -2022,6 +2026,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
case UI_BTYPE_HOTKEY_EVENT:
case UI_BTYPE_KEY_EVENT:
case UI_BTYPE_COLOR:
+ case UI_BTYPE_DECORATOR:
is_push = -1;
break;
case UI_BTYPE_BUT_TOGGLE:
@@ -2324,7 +2329,8 @@ bool ui_but_supports_cycling(const uiBut *but)
{
return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) ||
(but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) ||
- (but->type == UI_BTYPE_COLOR && but->a1 != -1) || (but->menu_step_func != NULL));
+ (but->type == UI_BTYPE_COLOR && ((uiButColor *)but)->is_pallete_color) ||
+ (but->menu_step_func != NULL));
}
double ui_but_value_get(uiBut *but)
@@ -2807,25 +2813,39 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
return str;
}
-static bool ui_set_but_string_eval_num_unit(bContext *C,
- uiBut *but,
- const char *str,
- double *r_value)
+/**
+ * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number
+ * as the Python error on it's own doesn't provide enough context.
+ */
+#define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details")
+
+static bool ui_number_from_string_units(
+ bContext *C, const char *str, const int unit_type, const UnitSettings *unit, double *r_value)
{
+ return user_string_to_number(C, str, unit, unit_type, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
+}
+
+static bool ui_number_from_string_units_with_but(bContext *C,
+ const char *str,
+ const uiBut *but,
+ double *r_value)
+{
+ const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
const UnitSettings *unit = but->block->unit;
- int type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but));
- return user_string_to_number(C, str, unit, type, r_value);
+ return ui_number_from_string_units(C, str, unit_type, unit, r_value);
}
static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
{
+ bool ok;
#ifdef WITH_PYTHON
- return BPY_execute_string_as_number(C, NULL, str, true, r_value);
+ ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value);
#else
UNUSED_VARS(C);
*r_value = atof(str);
- return true;
+ ok = true;
#endif
+ return ok;
}
static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
@@ -2859,7 +2879,7 @@ static bool ui_number_from_string_percentage(bContext *C, const char *str, doubl
return ui_number_from_string(C, str, r_value);
}
-bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
+bool ui_but_string_eval_number(bContext *C, const uiBut *but, const char *str, double *r_value)
{
if (str[0] == '\0') {
*r_value = 0.0;
@@ -2873,7 +2893,7 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
if (ui_but_is_float(but)) {
if (ui_but_is_unit(but)) {
- return ui_set_but_string_eval_num_unit(C, but, str, r_value);
+ return ui_number_from_string_units_with_but(C, str, but, r_value);
}
if (subtype == PROP_FACTOR) {
return ui_number_from_string_factor(C, str, r_value);
@@ -2932,10 +2952,10 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL, NULL);
return true;
}
+
+ uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but : NULL;
/* RNA pointer */
PointerRNA rptr;
- PointerRNA ptr = but->rnasearchpoin;
- PropertyRNA *prop = but->rnasearchprop;
/* This is kind of hackish, in theory think we could only ever use the second member of
* this if/else, since ui_searchbox_apply() is supposed to always set that pointer when
@@ -2943,12 +2963,16 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
* to try to break as little as possible existing code. All this is band-aids anyway.
* Fact remains, using editstr as main 'reference' over whole search button thingy
* is utterly weak and should be redesigned imho, but that's not a simple task. */
- if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
+ if (search_but && search_but->rnasearchprop &&
+ RNA_property_collection_lookup_string(
+ &search_but->rnasearchpoin, search_but->rnasearchprop, str, &rptr)) {
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
- else if (but->func_arg2 != NULL) {
- RNA_pointer_create(
- NULL, RNA_property_pointer_type(&but->rnapoin, but->rnaprop), but->func_arg2, &rptr);
+ else if (search_but->item_active != NULL) {
+ RNA_pointer_create(NULL,
+ RNA_property_pointer_type(&but->rnapoin, but->rnaprop),
+ search_but->item_active,
+ &rptr);
RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
@@ -3013,7 +3037,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
/* number editing */
double value;
- if (ui_but_string_set_eval_num(C, but, str, &value) == false) {
+ if (ui_but_string_eval_number(C, but, str, &value) == false) {
WM_report_banner_show();
return false;
}
@@ -3218,6 +3242,28 @@ void ui_but_range_set_soft(uiBut *but)
/* ******************* Free ********************/
+/**
+ * Free data specific to a certain button type.
+ * For now just do in a switch-case, we could instead have a callback stored in #uiBut and set that
+ * in #ui_but_alloc_info().
+ */
+static void ui_but_free_type_specific(uiBut *but)
+{
+ switch (but->type) {
+ case UI_BTYPE_SEARCH_MENU: {
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ if (search_but->arg_free_fn) {
+ search_but->arg_free_fn(search_but->arg);
+ search_but->arg = NULL;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
/* can be called with C==NULL */
static void ui_but_free(const bContext *C, uiBut *but)
{
@@ -3238,13 +3284,7 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->hold_argN);
}
- if (but->search != NULL) {
- if (but->search->arg_free_fn) {
- but->search->arg_free_fn(but->search->arg);
- but->search->arg = NULL;
- }
- MEM_freeN(but->search);
- }
+ ui_but_free_type_specific(but);
if (but->active) {
/* XXX solve later, buttons should be free-able without context ideally,
@@ -3377,7 +3417,7 @@ void UI_block_region_set(uiBlock *block, ARegion *region)
block->oldblock = oldblock;
}
-uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, short dt)
+uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, char emboss)
{
uiBlock *block;
wmWindow *window;
@@ -3388,7 +3428,7 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
block = MEM_callocN(sizeof(uiBlock), "uiBlock");
block->active = 1;
- block->dt = dt;
+ block->emboss = emboss;
block->evil_C = (void *)C; /* XXX */
if (scn) {
@@ -3427,12 +3467,12 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
char UI_block_emboss_get(uiBlock *block)
{
- return block->dt;
+ return block->emboss;
}
-void UI_block_emboss_set(uiBlock *block, char dt)
+void UI_block_emboss_set(uiBlock *block, char emboss)
{
- block->dt = dt;
+ block->emboss = emboss;
}
void UI_block_theme_style_set(uiBlock *block, char theme_style)
@@ -3723,16 +3763,109 @@ void ui_block_cm_to_display_space_v3(uiBlock *block, float pixel[3])
IMB_colormanagement_scene_linear_to_display_v3(pixel, display);
}
-static uiBut *ui_but_alloc(const eButType type)
+static void ui_but_alloc_info(const eButType type,
+ size_t *r_alloc_size,
+ const char **r_alloc_str,
+ bool *r_has_custom_type)
{
+ size_t alloc_size;
+ const char *alloc_str;
+ bool has_custom_type = true;
+
switch (type) {
+ case UI_BTYPE_COLOR:
+ alloc_size = sizeof(uiButColor);
+ alloc_str = "uiButColor";
+ break;
+ case UI_BTYPE_DECORATOR:
+ alloc_size = sizeof(uiButDecorator);
+ alloc_str = "uiButDecorator";
+ break;
case UI_BTYPE_TAB:
- return MEM_callocN(sizeof(uiButTab), "uiButTab");
+ alloc_size = sizeof(uiButTab);
+ alloc_str = "uiButTab";
+ break;
+ case UI_BTYPE_SEARCH_MENU:
+ alloc_size = sizeof(uiButSearch);
+ alloc_str = "uiButSearch";
+ break;
+ case UI_BTYPE_PROGRESS_BAR:
+ alloc_size = sizeof(uiButProgressbar);
+ alloc_str = "uiButProgressbar";
+ break;
default:
- return MEM_callocN(sizeof(uiBut), "uiBut");
+ alloc_size = sizeof(uiBut);
+ alloc_str = "uiBut";
+ has_custom_type = false;
+ break;
+ }
+
+ if (r_alloc_size) {
+ *r_alloc_size = alloc_size;
+ }
+ if (r_alloc_str) {
+ *r_alloc_str = alloc_str;
+ }
+ if (r_has_custom_type) {
+ *r_has_custom_type = has_custom_type;
}
}
+static uiBut *ui_but_alloc(const eButType type)
+{
+ size_t alloc_size;
+ const char *alloc_str;
+
+ ui_but_alloc_info(type, &alloc_size, &alloc_str, NULL);
+
+ return MEM_callocN(alloc_size, alloc_str);
+}
+
+/**
+ * Reallocate the button (new address is returned) for a new button type.
+ * This should generally be avoided and instead the correct type be created right away.
+ *
+ * \note Only the #uiBut data can be kept. If the old button used a derived type (e.g. #uiButTab),
+ * the data that is not inside #uiBut will be lost.
+ */
+uiBut *ui_but_change_type(uiBut *but, eButType new_type)
+{
+ if (but->type != new_type) {
+ size_t alloc_size;
+ const char *alloc_str;
+ uiBut *insert_after_but = but->prev;
+ bool new_has_custom_type, old_has_custom_type;
+
+ /* Remove old button address */
+ BLI_remlink(&but->block->buttons, but);
+
+ ui_but_alloc_info(but->type, NULL, NULL, &old_has_custom_type);
+ ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type);
+
+ if (new_has_custom_type || old_has_custom_type) {
+ const void *old_but_ptr = but;
+ /* Button may have pointer to a member within itself, this will have to be updated. */
+ const bool has_str_ptr_to_self = but->str == but->strdata;
+
+ but = MEM_recallocN_id(but, alloc_size, alloc_str);
+ but->type = new_type;
+ if (has_str_ptr_to_self) {
+ but->str = but->strdata;
+ }
+
+ BLI_insertlinkafter(&but->block->buttons, insert_after_but, but);
+
+ if (but->layout) {
+ const bool found_layout = ui_layout_replace_but_ptr(but->layout, old_but_ptr, but);
+ BLI_assert(found_layout);
+ UNUSED_VARS_NDEBUG(found_layout);
+ }
+ }
+ }
+
+ return but;
+}
+
/**
* \brief ui_def_but is the function that draws many button types
*
@@ -3812,7 +3945,7 @@ static uiBut *ui_def_but(uiBlock *block,
but->tip = tip;
but->disabled_info = block->lockstr;
- but->dt = block->dt;
+ but->emboss = block->emboss;
but->pie_dir = UI_RADIAL_NONE;
but->block = block; /* pointer back, used for frontbuffer status, and picker */
@@ -3878,6 +4011,7 @@ static uiBut *ui_def_but(uiBlock *block,
if (ELEM(but->type,
UI_BTYPE_BLOCK,
UI_BTYPE_BUT,
+ UI_BTYPE_DECORATOR,
UI_BTYPE_LABEL,
UI_BTYPE_PULLDOWN,
UI_BTYPE_ROUNDBOX,
@@ -4345,7 +4479,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
}
if (type == UI_BTYPE_MENU) {
- if (but->dt == UI_EMBOSS_PULLDOWN) {
+ if (but->emboss == UI_EMBOSS_PULLDOWN) {
ui_but_submenu_enable(block, but);
}
}
@@ -6372,54 +6506,55 @@ void UI_but_func_search_set(uiBut *but,
uiButHandleFunc search_exec_fn,
void *active)
{
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
/* needed since callers don't have access to internal functions
* (as an alternative we could expose it) */
if (search_create_fn == NULL) {
search_create_fn = ui_searchbox_create_generic;
}
- struct uiButSearchData *search = but->search;
- if (search != NULL) {
- if (search->arg_free_fn != NULL) {
- search->arg_free_fn(but->search->arg);
- search->arg = NULL;
- }
- }
- else {
- search = MEM_callocN(sizeof(*but->search), __func__);
- but->search = search;
+ if (search_but->arg_free_fn != NULL) {
+ search_but->arg_free_fn(search_but->arg);
+ search_but->arg = NULL;
}
- search->create_fn = search_create_fn;
- search->update_fn = search_update_fn;
+ search_but->popup_create_fn = search_create_fn;
+ search_but->items_update_fn = search_update_fn;
+ search_but->item_active = active;
- search->arg = arg;
- search->arg_free_fn = search_arg_free_fn;
+ search_but->arg = arg;
+ search_but->arg_free_fn = search_arg_free_fn;
if (search_exec_fn) {
#ifdef DEBUG
- if (but->func) {
+ if (search_but->but.func) {
/* watch this, can be cause of much confusion, see: T47691 */
printf("%s: warning, overwriting button callback with search function callback!\n",
__func__);
}
#endif
- UI_but_func_set(but, search_exec_fn, search->arg, active);
+ /* Handling will pass the active item as arg2 later, so keep it NULL here. */
+ UI_but_func_set(but, search_exec_fn, search_but->arg, NULL);
}
/* search buttons show red-alert if item doesn't exist, not for menus */
if (0 == (but->block->flag & UI_BLOCK_LOOP)) {
/* skip empty buttons, not all buttons need input, we only show invalid */
if (but->drawstr[0]) {
- ui_but_search_refresh(but);
+ ui_but_search_refresh(search_but);
}
}
}
void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn context_menu_fn)
{
- struct uiButSearchData *search = but->search;
- search->context_menu_fn = context_menu_fn;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_context_menu_fn = context_menu_fn;
}
/**
@@ -6428,14 +6563,18 @@ void UI_but_func_search_set_context_menu(uiBut *but, uiButSearchContextMenuFn co
*/
void UI_but_func_search_set_sep_string(uiBut *but, const char *search_sep_string)
{
- struct uiButSearchData *search = but->search;
- search->sep_string = search_sep_string;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_sep_string = search_sep_string;
}
void UI_but_func_search_set_tooltip(uiBut *but, uiButSearchTooltipFn tooltip_fn)
{
- struct uiButSearchData *search = but->search;
- search->tooltip_fn = tooltip_fn;
+ uiButSearch *but_search = (uiButSearch *)but;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ but_search->item_tooltip_fn = tooltip_fn;
}
/* Callbacks for operator search button. */
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index 8d12a1dd1ad..cc58082cb02 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -120,35 +120,41 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context)
}
}
-static uiBut *ui_but_anim_decorate_find_attached_button(uiBut *but_decorate)
+static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate)
{
uiBut *but_iter = NULL;
- BLI_assert(UI_but_is_decorator(but_decorate));
- BLI_assert(but_decorate->rnasearchpoin.data && but_decorate->rnasearchprop);
+ BLI_assert(UI_but_is_decorator(&but_decorate->but));
+ BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop);
- LISTBASE_CIRCULAR_BACKWARD_BEGIN (&but_decorate->block->buttons, but_iter, but_decorate->prev) {
- if (but_iter != but_decorate &&
- ui_but_rna_equals_ex(but_iter,
- &but_decorate->rnasearchpoin,
- but_decorate->rnasearchprop,
- POINTER_AS_INT(but_decorate->custom_data))) {
+ LISTBASE_CIRCULAR_BACKWARD_BEGIN (
+ &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) {
+ if (but_iter != (uiBut *)but_decorate &&
+ ui_but_rna_equals_ex(
+ but_iter, &but_decorate->rnapoin, but_decorate->rnaprop, but_decorate->rnaindex)) {
return but_iter;
}
}
- LISTBASE_CIRCULAR_BACKWARD_END(&but_decorate->block->buttons, but_iter, but_decorate->prev);
+ LISTBASE_CIRCULAR_BACKWARD_END(
+ &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev);
return NULL;
}
-void ui_but_anim_decorate_update_from_flag(uiBut *but)
+void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but)
{
- const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but);
+ if (!decorator_but->rnapoin.data || !decorator_but->rnaprop) {
+ /* Nothing to do. */
+ return;
+ }
+
+ const uiBut *but_anim = ui_but_anim_decorate_find_attached_button(decorator_but);
+ uiBut *but = &decorator_but->but;
if (!but_anim) {
printf("Could not find button with matching property to decorate (%s.%s)\n",
- RNA_struct_identifier(but->rnasearchpoin.type),
- RNA_property_identifier(but->rnasearchprop));
+ RNA_struct_identifier(decorator_but->rnapoin.type),
+ RNA_property_identifier(decorator_but->rnaprop));
return;
}
@@ -325,7 +331,7 @@ void ui_but_anim_paste_driver(bContext *C)
void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy))
{
wmWindowManager *wm = CTX_wm_manager(C);
- uiBut *but_decorate = arg_but;
+ uiButDecorator *but_decorate = arg_but;
uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate);
if (!but_anim) {
@@ -333,7 +339,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)
}
/* FIXME(campbell), swapping active pointer is weak. */
- SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
+ SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
wm->op_undo_depth++;
if (but_anim->flag & UI_BUT_DRIVEN) {
@@ -357,6 +363,6 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)
WM_operator_properties_free(&props_ptr);
}
- SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->active);
+ SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active);
wm->op_undo_depth--;
}
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index a08c5c45b6f..46876fca9a5 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -407,7 +407,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
"'%s').label",
idname);
char *expr_result = NULL;
- if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
STRNCPY(drawstr, expr_result);
MEM_freeN(expr_result);
}
@@ -962,7 +962,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
const PropertyType prop_type = RNA_property_type(but->rnaprop);
if (((prop_type == PROP_POINTER) ||
(prop_type == PROP_STRING && but->type == UI_BTYPE_SEARCH_MENU &&
- but->search->update_fn == ui_rna_collection_search_update_fn)) &&
+ ((uiButSearch *)but)->items_update_fn == ui_rna_collection_search_update_fn)) &&
ui_jump_to_target_button_poll(C)) {
uiItemO(layout,
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Jump to Target"),
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index cc5d21c3df3..05f6e61ff40 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -773,9 +773,8 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region),
(float)rect->ymin,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
ibuf->rect,
1.0f,
1.0f,
@@ -841,7 +840,7 @@ static void draw_scope_end(const rctf *rect, GLint *scissor)
/* outline */
UI_draw_roundbox_corner_set(UI_CNR_ALL);
- float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 0.5f};
UI_draw_roundbox_4fv(
false, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f, color);
}
@@ -859,7 +858,7 @@ static void histogram_draw_one(float r,
const bool is_line,
uint pos_attr)
{
- float color[4] = {r, g, b, alpha};
+ const float color[4] = {r, g, b, alpha};
/* that can happen */
if (res == 0) {
@@ -1033,7 +1032,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
Scopes *scopes = (Scopes *)but->poin;
int scissor[4];
float colors[3][3];
- float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
+ const float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
/* colors pre multiplied by alpha for speed up */
float colors_alpha[3][3], colorsycc_alpha[3][3];
float min, max;
@@ -1173,7 +1172,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region),
/* LUMA (1 channel) */
if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {
- float col[3] = {alpha, alpha, alpha};
+ const float col[3] = {alpha, alpha, alpha};
GPU_matrix_push();
GPU_matrix_translate_2f(rect.xmin, yofs);
@@ -1466,7 +1465,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region),
if (scopes->ok && scopes->vecscope != NULL) {
/* pixel point cloud */
- float col[3] = {alpha, alpha, alpha};
+ const float col[3] = {alpha, alpha, alpha};
GPU_blend_set_func(GPU_ONE, GPU_ONE);
GPU_point_size(1.0);
@@ -1774,7 +1773,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const
void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rect)
{
/* sphere color */
- float diffuse[3] = {1.0f, 1.0f, 1.0f};
+ const float diffuse[3] = {1.0f, 1.0f, 1.0f};
float light[3];
const float size = 0.5f * min_ff(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
@@ -1938,7 +1937,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol,
/* Do this first to not mess imm context */
if (but->a1 == UI_GRAD_H) {
/* magic trigger for curve backgrounds */
- float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
+ const float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */
rcti grid = {
.xmin = rect->xmin + zoomx * (-offsx),
@@ -2257,12 +2256,12 @@ void ui_draw_but_CURVEPROFILE(ARegion *region,
/* Also add the last points on the right and bottom edges to close off the fill polygon. */
bool add_left_tri = profile->view_rect.xmin < 0.0f;
bool add_bottom_tri = profile->view_rect.ymin < 0.0f;
- uint tot_points = (uint)PROF_N_TABLE(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
+ uint tot_points = (uint)PROF_TABLE_LEN(profile->path_len) + 1 + add_left_tri + add_bottom_tri;
uint tot_triangles = tot_points - 2;
/* Create array of the positions of the table's points. */
float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords");
- for (i = 0; i < (uint)PROF_N_TABLE(profile->path_len);
+ for (i = 0; i < (uint)PROF_TABLE_LEN(profile->path_len);
i++) { /* Only add the points from the table here. */
table_coords[i][0] = pts[i].x;
table_coords[i][1] = pts[i].y;
@@ -2484,7 +2483,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
(rect.ymax + 1) - (rect.ymin - 1));
if (scopes->track_disabled) {
- float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
+ const float color[4] = {0.7f, 0.3f, 0.3f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
@@ -2533,7 +2532,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
float col_sel[4], col_outline[4];
if (scopes->use_track_mask) {
- float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
@@ -2545,9 +2544,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
rect.ymin + 1,
drawibuf->x,
drawibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_LINEAR,
+ GPU_RGBA8,
+ true,
drawibuf->rect,
1.0f,
1.0f,
@@ -2567,7 +2565,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
/* Do stipple cross with geometry */
immBegin(GPU_PRIM_LINES, 7 * 2 * 2);
- float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
+ const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f};
for (int axe = 0; axe < 2; axe++) {
for (int i = 0; i < 7; i++) {
float x1 = pos_sel[i] * (1 - axe);
@@ -2597,7 +2595,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region),
}
if (!ok) {
- float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(
true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color);
@@ -2775,7 +2773,7 @@ void ui_draw_dropshadow(
GPU_batch_draw(batch);
/* outline emphasis */
- float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 0.4f};
UI_draw_roundbox_4fv(false,
rct->xmin - 0.5f,
rct->ymin - 0.5f,
diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c
index 93b052b3b69..c86e35f91db 100644
--- a/source/blender/editors/interface/interface_eyedropper_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_color.c
@@ -39,8 +39,6 @@
#include "RNA_access.h"
-#include "GPU_glew.h"
-
#include "UI_interface.h"
#include "IMB_colormanagement.h"
@@ -174,7 +172,7 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, mx, my);
if (region) {
SpaceNode *snode = area->spacedata.first;
- int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
+ const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
if (ED_space_node_color_sample(bmain, snode, region, mval, r_col)) {
return;
@@ -196,7 +194,7 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3])
if (win) {
/* Fallback to simple opengl picker. */
- int mval[2] = {mx, my};
+ const int mval[2] = {mx, my};
WM_window_pixel_sample_read(wm, win, mval, r_col);
IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
}
diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c
index 7b8357f5ef1..b757341ae13 100644
--- a/source/blender/editors/interface/interface_eyedropper_colorband.c
+++ b/source/blender/editors/interface/interface_eyedropper_colorband.c
@@ -179,8 +179,8 @@ static void eyedropper_colorband_sample_segment(bContext *C,
/* Since the mouse tends to move rather rapidly we use #BLI_bitmap_draw_2d_line_v2v2i
* to interpolate between the reported coordinates */
struct EyedropperColorband_Context userdata = {C, eye};
- int p1[2] = {eye->last_x, eye->last_y};
- int p2[2] = {mx, my};
+ const int p1[2] = {eye->last_x, eye->last_y};
+ const int p2[2] = {mx, my};
BLI_bitmap_draw_2d_line_v2v2i(p1, p2, eyedropper_colorband_sample_callback, &userdata);
}
diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
index 978d8ac09de..aa5b4d2c255 100644
--- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
+++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c
@@ -106,8 +106,11 @@ static void eyedropper_gpencil_exit(bContext *C, wmOperator *op)
MEM_SAFE_FREE(op->customdata);
}
-static void eyedropper_add_material(
- bContext *C, float col_conv[4], const bool only_stroke, const bool only_fill, const bool both)
+static void eyedropper_add_material(bContext *C,
+ const float col_conv[4],
+ const bool only_stroke,
+ const bool only_fill,
+ const bool both)
{
Main *bmain = CTX_data_main(C);
Object *ob = CTX_data_active_object(C);
@@ -193,7 +196,7 @@ static void eyedropper_add_material(
}
/* Create a new palette color and palette if needed. */
-static void eyedropper_add_palette_color(bContext *C, float col_conv[4])
+static void eyedropper_add_palette_color(bContext *C, const float col_conv[4])
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index bcb4f7c672f..999ddca65b9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -767,11 +767,12 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->rnapoin = but->rnapoin;
after->rnaprop = but->rnaprop;
- if (but->search != NULL) {
- after->search_arg_free_fn = but->search->arg_free_fn;
- after->search_arg = but->search->arg;
- but->search->arg_free_fn = NULL;
- but->search->arg = NULL;
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
+ uiButSearch *search_but = (uiButSearch *)but;
+ after->search_arg_free_fn = search_but->arg_free_fn;
+ after->search_arg = search_but->arg;
+ search_but->arg_free_fn = NULL;
+ search_but->arg = NULL;
}
if (but->context) {
@@ -1047,8 +1048,19 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data)
but->rename_orig = data->origstr;
data->origstr = NULL;
}
+
+ void *orig_arg2 = but->func_arg2;
+
+ /* If arg2 isn't in use already, pass the active search item through it. */
+ if ((but->func_arg2 == NULL) && (but->type == UI_BTYPE_SEARCH_MENU)) {
+ uiButSearch *search_but = (uiButSearch *)but;
+ but->func_arg2 = search_but->item_active;
+ }
+
ui_apply_but_func(C, but);
+ but->func_arg2 = orig_arg2;
+
data->retval = but->retval;
data->applied = true;
}
@@ -2087,6 +2099,7 @@ static void ui_apply_but(
/* handle different types */
switch (but->type) {
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
ui_apply_but_BUT(C, but, data);
break;
case UI_BTYPE_TEXT:
@@ -2367,7 +2380,7 @@ static void ui_but_paste_numeric_value(bContext *C,
{
double value;
- if (ui_but_string_set_eval_num(C, but, buf_paste, &value)) {
+ if (ui_but_string_eval_number(C, but, buf_paste, &value)) {
button_activate_state(C, but, BUTTON_STATE_NUM_EDITING);
data->value = value;
ui_but_string_set(C, but, buf_paste);
@@ -3023,7 +3036,7 @@ static bool ui_textedit_insert_buf(uiBut *but,
static bool ui_textedit_insert_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
{
- char buf[2] = {ascii, '\0'};
+ const char buf[2] = {ascii, '\0'};
if (UI_but_is_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
printf(
@@ -3321,7 +3334,9 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
/* optional searchbox */
if (but->type == UI_BTYPE_SEARCH_MENU) {
- data->searchbox = but->search->create_fn(C, data->region, but);
+ uiButSearch *search_but = (uiButSearch *)but;
+
+ data->searchbox = search_but->popup_create_fn(C, data->region, search_but);
ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
}
@@ -4390,7 +4405,7 @@ static int ui_do_but_TEX(
if (ELEM(event->type, EVT_PADENTER, EVT_RETKEY) && (!UI_but_is_utf8(but))) {
/* pass - allow filesel, enter to execute */
}
- else if (but->dt == UI_EMBOSS_NONE && !event->ctrl) {
+ else if (but->emboss == UI_EMBOSS_NONE && !event->ctrl) {
/* pass */
}
else {
@@ -5698,21 +5713,24 @@ static bool ui_numedit_but_UNITVEC(
return changed;
}
-static void ui_palette_set_active(uiBut *but)
+static void ui_palette_set_active(uiButColor *color_but)
{
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
- Palette *palette = (Palette *)but->rnapoin.owner_id;
- PaletteColor *color = but->rnapoin.data;
+ if (color_but->is_pallete_color) {
+ Palette *palette = (Palette *)color_but->but.rnapoin.owner_id;
+ PaletteColor *color = color_but->but.rnapoin.data;
palette->active_color = BLI_findindex(&palette->colors, color);
}
}
static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
+ BLI_assert(but->type == UI_BTYPE_COLOR);
+ uiButColor *color_but = (uiButColor *)but;
+
if (data->state == BUTTON_STATE_HIGHLIGHT) {
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
if (ui_but_contains_point_px_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
@@ -5722,7 +5740,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
#ifdef USE_DRAG_TOGGLE
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -5731,7 +5749,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
#endif
/* regular open menu */
if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY) && event->val == KM_PRESS) {
- ui_palette_set_active(but);
+ ui_palette_set_active(color_but);
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
@@ -5762,8 +5780,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
ui_apply_but(C, but->block, but, data, true);
return WM_UI_HANDLER_BREAK;
}
- if ((int)(but->a1) == UI_PALETTE_COLOR && event->type == EVT_DELKEY &&
- event->val == KM_PRESS) {
+ if (color_but->is_pallete_color && (event->type == EVT_DELKEY) && (event->val == KM_PRESS)) {
Palette *palette = (Palette *)but->rnapoin.owner_id;
PaletteColor *color = but->rnapoin.data;
@@ -5794,7 +5811,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
- if ((int)(but->a1) == UI_PALETTE_COLOR) {
+ if (color_but->is_pallete_color) {
if (!event->ctrl) {
float color[3];
Paint *paint = BKE_paint_get_active_from_context(C);
@@ -6955,7 +6972,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block,
fy *= mval_factor;
/* Move all selected points. */
- float delta[2] = {fx, fy};
+ const float delta[2] = {fx, fy};
for (a = 0; a < profile->path_len; a++) {
/* Don't move the last and first control points. */
if ((pts[a].flag & PROF_SELECT) && (a != 0) && (a != profile->path_len)) {
@@ -7129,7 +7146,7 @@ static int ui_do_but_CURVEPROFILE(
dist_min_sq = square_f(U.dpi_fac * 8.0f); /* 8 pixel radius from each table point. */
/* Loop through the path's high resolution table and find what's near the click. */
- for (int i = 1; i <= PROF_N_TABLE(profile->path_len); i++) {
+ for (int i = 1; i <= PROF_TABLE_LEN(profile->path_len); i++) {
copy_v2_v2(f_xy_prev, f_xy);
BLI_rctf_transform_pt_v(&but->rect, &profile->view_rect, f_xy, &table[i].x);
@@ -7522,6 +7539,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
switch (but->type) {
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
retval = ui_do_but_BUT(C, but, data, event);
break;
case UI_BTYPE_KEY_EVENT:
@@ -7597,13 +7615,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
retval = ui_do_but_BUT(C, but, data, event);
break;
case UI_BTYPE_COLOR:
- if (but->a1 == -1) {
- /* signal to prevent calling up color picker */
- retval = ui_do_but_EXIT(C, but, data, event);
- }
- else {
- retval = ui_do_but_COLOR(C, but, data, event);
- }
+ retval = ui_do_but_COLOR(C, but, data, event);
break;
case UI_BTYPE_UNITVEC:
retval = ui_do_but_UNITVEC(C, block, but, data, event);
@@ -8430,7 +8442,7 @@ void UI_context_update_anim_flag(const bContext *C)
ui_but_anim_flag(but, &anim_eval_context);
ui_but_override_flag(CTX_data_main(C), but);
if (UI_but_is_decorator(but)) {
- ui_but_anim_decorate_update_from_flag(but);
+ ui_but_anim_decorate_update_from_flag((uiButDecorator *)but);
}
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 586f5e07997..a7b7bad2fe6 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1517,18 +1517,8 @@ static void icon_draw_rect(float x,
immUniform1f("factor", desaturate);
}
- immDrawPixelsTex(&state,
- draw_x,
- draw_y,
- draw_w,
- draw_h,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- rect,
- 1.0f,
- 1.0f,
- col);
+ immDrawPixelsTex(
+ &state, draw_x, draw_y, draw_w, draw_h, GPU_RGBA8, false, rect, 1.0f, 1.0f, col);
if (ima) {
IMB_freeImBuf(ima);
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
index fed29571185..4be2dbc0b4e 100644
--- a/source/blender/editors/interface/interface_icons_event.c
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -143,7 +143,7 @@ void icon_draw_rect_input(float x,
};
if ((event_type >= EVT_AKEY) && (event_type <= EVT_ZKEY)) {
- char str[2] = {'A' + (event_type - EVT_AKEY), '\0'};
+ const char str[2] = {'A' + (event_type - EVT_AKEY), '\0'};
icon_draw_rect_input_text(&rect, color, str, 13);
}
else if ((event_type >= EVT_F1KEY) && (event_type <= EVT_F12KEY)) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index ab5d8806837..41110883729 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -147,19 +147,11 @@ enum {
/* max amount of items a radial menu (pie menu) can contain */
#define PIE_MAX_ITEMS 8
-struct uiButSearchData {
- uiButSearchCreateFn create_fn;
- uiButSearchUpdateFn update_fn;
- void *arg;
- uiButSearchArgFreeFn arg_free_fn;
- uiButSearchContextMenuFn context_menu_fn;
- uiButSearchTooltipFn tooltip_fn;
-
- const char *sep_string;
-};
-
struct uiBut {
struct uiBut *next, *prev;
+
+ /* Pointer back to the layout item holding this button. */
+ uiLayout *layout;
int flag, drawflag;
eButType type;
eButPointerType pointype;
@@ -185,8 +177,6 @@ struct uiBut {
* - UI_BTYPE_LABEL: Use `(a1 == 1.0f)` to use a2 as a blending factor (imaginative!).
* - UI_BTYPE_SCROLL: Use as scroll size.
* - UI_BTYPE_SEARCH_MENU: Use as number or rows.
- * - UI_BTYPE_COLOR: Use as indication of color palette.
- * - UI_BTYPE_PROGRESS_BAR: Use to store progress (0..1).
*/
float a1;
@@ -196,7 +186,6 @@ struct uiBut {
* - UI_BTYPE_NUM: Use to store RNA 'precision' value, for dragging and click-step.
* - UI_BTYPE_LABEL: If `(a1 == 1.0f)` use a2 as a blending factor.
* - UI_BTYPE_SEARCH_MENU: Use as number or columns.
- * - UI_BTYPE_COLOR: Use as index in palette (not so good, needs refactor).
*/
float a2;
@@ -214,8 +203,6 @@ struct uiBut {
uiButCompleteFunc autocomplete_func;
void *autofunc_arg;
- struct uiButSearchData *search;
-
uiButHandleRenameFunc rename_func;
void *rename_arg1;
void *rename_orig;
@@ -232,8 +219,8 @@ struct uiBut {
const char *disabled_info;
BIFIconID icon;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the block */
- char dt;
+ /** emboss: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied from the #uiBlock.emboss */
+ char emboss;
/** direction in a pie menu, used for collision detection (RadialDirection) */
signed char pie_dir;
/** could be made into a single flag */
@@ -256,9 +243,6 @@ struct uiBut {
struct PropertyRNA *rnaprop;
int rnaindex;
- struct PointerRNA rnasearchpoin;
- struct PropertyRNA *rnasearchprop;
-
/* Operator data */
struct wmOperatorType *optype;
struct PointerRNA *opptr;
@@ -294,11 +278,56 @@ struct uiBut {
uiBlock *block;
};
+/** Derived struct for #UI_BTYPE_COLOR */
+typedef struct uiButColor {
+ uiBut but;
+
+ bool is_pallete_color;
+ int palette_color_index;
+} uiButColor;
+
+/** Derived struct for #UI_BTYPE_TAB */
typedef struct uiButTab {
uiBut but;
struct MenuType *menu;
} uiButTab;
+/** Derived struct for #UI_BTYPE_SEARCH_MENU */
+typedef struct uiButSearch {
+ uiBut but;
+
+ uiButSearchCreateFn popup_create_fn;
+ uiButSearchUpdateFn items_update_fn;
+ void *item_active;
+
+ void *arg;
+ uiButSearchArgFreeFn arg_free_fn;
+
+ uiButSearchContextMenuFn item_context_menu_fn;
+ uiButSearchTooltipFn item_tooltip_fn;
+
+ const char *item_sep_string;
+
+ struct PointerRNA rnasearchpoin;
+ struct PropertyRNA *rnasearchprop;
+} uiButSearch;
+
+/** Derived struct for #UI_BTYPE_DECORATOR */
+typedef struct uiButDecorator {
+ uiBut but;
+
+ struct PointerRNA rnapoin;
+ struct PropertyRNA *rnaprop;
+ int rnaindex;
+} uiButDecorator;
+
+typedef struct uiButProgressbar {
+ uiBut but;
+
+ /* 0..1 range */
+ float progress;
+} uiButProgressbar;
+
/**
* Additional, superimposed icon for a button, invoking an operator.
*/
@@ -404,8 +433,8 @@ struct uiBlock {
char direction;
/** UI_BLOCK_THEME_STYLE_* */
char theme_style;
- /** drawtype: UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to buttons */
- char dt;
+ /** UI_EMBOSS, UI_EMBOSS_NONE ... etc, copied to #uiBut.emboss */
+ char emboss;
bool auto_open;
char _pad[5];
double auto_open_last;
@@ -493,6 +522,8 @@ extern void ui_window_to_region_rcti(const struct ARegion *region,
extern void ui_region_to_window(const struct ARegion *region, int *x, int *y);
extern void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r_rect);
+uiBut *ui_but_change_type(uiBut *but, eButType new_type);
+
extern double ui_but_value_get(uiBut *but);
extern void ui_but_value_set(uiBut *but, double value);
extern void ui_but_hsv_set(uiBut *but);
@@ -516,10 +547,10 @@ extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_N
extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size);
extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
extern bool ui_but_string_set(struct bContext *C, uiBut *but, const char *str) ATTR_NONNULL();
-extern bool ui_but_string_set_eval_num(struct bContext *C,
- uiBut *but,
- const char *str,
- double *value) ATTR_NONNULL();
+extern bool ui_but_string_eval_number(struct bContext *C,
+ const uiBut *but,
+ const char *str,
+ double *value) ATTR_NONNULL();
extern int ui_but_string_get_max_length(uiBut *but);
/* Clear & exit the active button's string. */
extern void ui_but_active_string_clear_and_exit(struct bContext *C, uiBut *but) ATTR_NONNULL();
@@ -662,13 +693,13 @@ ColorPicker *ui_block_colorpicker_create(struct uiBlock *block);
/* Searchbox for string button */
struct ARegion *ui_searchbox_create_generic(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
struct ARegion *ui_searchbox_create_operator(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
struct ARegion *ui_searchbox_create_menu(struct bContext *C,
struct ARegion *butregion,
- uiBut *but);
+ uiButSearch *search_but);
bool ui_searchbox_inside(struct ARegion *region, int x, int y);
int ui_searchbox_find_index(struct ARegion *region, const char *name);
@@ -681,7 +712,7 @@ bool ui_searchbox_event(struct bContext *C,
const struct wmEvent *event);
bool ui_searchbox_apply(uiBut *but, struct ARegion *region);
void ui_searchbox_free(struct bContext *C, struct ARegion *region);
-void ui_but_search_refresh(uiBut *but);
+void ui_but_search_refresh(uiButSearch *but);
/* interface_region_menu_popup.c */
int ui_but_menu_step(uiBut *but, int step);
@@ -925,11 +956,12 @@ void ui_resources_free(void);
/* interface_layout.c */
void ui_layout_add_but(uiLayout *layout, uiBut *but);
-void ui_but_add_search(uiBut *but,
- PointerRNA *ptr,
- PropertyRNA *prop,
- PointerRNA *searchptr,
- PropertyRNA *searchprop);
+bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but);
+uiBut *ui_but_add_search(uiBut *but,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ PointerRNA *searchptr,
+ PropertyRNA *searchprop);
void ui_layout_list_set_labels_active(uiLayout *layout);
/* menu callback */
void ui_item_menutype_func(struct bContext *C, struct uiLayout *layout, void *arg_mt);
@@ -950,7 +982,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str);
void ui_but_anim_autokey(struct bContext *C, uiBut *but, struct Scene *scene, float cfra);
void ui_but_anim_decorate_cb(struct bContext *C, void *arg_but, void *arg_dummy);
-void ui_but_anim_decorate_update_from_flag(uiBut *but);
+void ui_but_anim_decorate_update_from_flag(uiButDecorator *but);
/* interface_query.c */
bool ui_but_is_editable(const uiBut *but) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index f1d1ef589a5..888cacb64eb 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -674,7 +674,7 @@ static void ui_item_array(uiLayout *layout,
/* show checkboxes for rna on a non-emboss block (menu for eg) */
if (type == PROP_BOOLEAN &&
- ELEM(layout->root->block->dt, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
+ ELEM(layout->root->block->emboss, UI_EMBOSS_NONE, UI_EMBOSS_PULLDOWN)) {
boolarr = MEM_callocN(sizeof(bool) * len, __func__);
RNA_property_boolean_get_array(ptr, prop, boolarr);
}
@@ -2278,7 +2278,7 @@ void uiItemFullR(uiLayout *layout,
/* property with separate label */
else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) {
but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag);
- ui_but_add_search(but, ptr, prop, NULL, NULL);
+ but = ui_but_add_search(but, ptr, prop, NULL, NULL);
if (layout->redalert) {
UI_but_flag_enable(but, UI_BUT_REDALERT);
@@ -2333,7 +2333,7 @@ void uiItemFullR(uiLayout *layout,
/* Mark non-embossed textfields inside a listbox. */
if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) &&
- (but->dt & UI_EMBOSS_NONE)) {
+ (but->emboss & UI_EMBOSS_NONE)) {
UI_but_flag_enable(but, UI_BUT_LIST_ITEM);
}
@@ -2651,7 +2651,10 @@ static void ui_rna_collection_search_arg_free_fn(void *ptr)
MEM_freeN(ptr);
}
-void ui_but_add_search(
+/**
+ * \note May reallocate \a but, so the possibly new address is returned.
+ */
+uiBut *ui_but_add_search(
uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop)
{
StructRNA *ptype;
@@ -2669,11 +2672,13 @@ void ui_but_add_search(
/* turn button into search button */
if (searchprop) {
uiRNACollectionSearch *coll_search = MEM_mallocN(sizeof(*coll_search), __func__);
+ uiButSearch *search_but;
- but->type = UI_BTYPE_SEARCH_MENU;
+ but = ui_but_change_type(but, UI_BTYPE_SEARCH_MENU);
+ search_but = (uiButSearch *)but;
+ search_but->rnasearchpoin = *searchptr;
+ search_but->rnasearchprop = searchprop;
but->hardmax = MAX2(but->hardmax, 256.0f);
- but->rnasearchpoin = *searchptr;
- but->rnasearchprop = searchprop;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
if (RNA_property_is_unlink(prop)) {
but->flag |= UI_BUT_VALUE_CLEAR;
@@ -2707,6 +2712,8 @@ void ui_but_add_search(
* so other code might have already set but->type to search menu... */
but->flag |= UI_BUT_DISABLED;
}
+
+ return but;
}
void uiItemPointerR_prop(uiLayout *layout,
@@ -2939,29 +2946,28 @@ void uiItemMContents(uiLayout *layout, const char *menuname)
void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index)
{
uiBlock *block = layout->root->block;
- uiBut *but = NULL;
-
uiLayout *col;
+
UI_block_layout_set_current(block, layout);
col = uiLayoutColumn(layout, false);
col->space = 0;
col->emboss = UI_EMBOSS_NONE;
if (ELEM(NULL, ptr, prop) || !RNA_property_animateable(ptr, prop)) {
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_BLANK1,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- "");
+ uiBut *but = uiDefIconBut(block,
+ UI_BTYPE_DECORATOR,
+ 0,
+ ICON_BLANK1,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ "");
but->flag |= UI_BUT_DISABLED;
return;
}
@@ -2971,27 +2977,28 @@ void uiItemDecoratorR_prop(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop,
/* Loop for the array-case, but only do in case of an expanded array. */
for (int i = 0; i < (is_expand ? RNA_property_array_length(ptr, prop) : 1); i++) {
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- 0,
- ICON_DOT,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Animate property"));
- UI_but_func_set(but, ui_but_anim_decorate_cb, but, NULL);
- but->flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
+ uiButDecorator *decorator_but = (uiButDecorator *)uiDefIconBut(block,
+ UI_BTYPE_DECORATOR,
+ 0,
+ ICON_DOT,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Animate property"));
+
+ UI_but_func_set(&decorator_but->but, ui_but_anim_decorate_cb, decorator_but, NULL);
+ decorator_but->but.flag |= UI_BUT_UNDO | UI_BUT_DRAG_LOCK;
/* Reusing RNA search members, setting actual RNA data has many side-effects. */
- but->rnasearchpoin = *ptr;
- but->rnasearchprop = prop;
+ decorator_but->rnapoin = *ptr;
+ decorator_but->rnaprop = prop;
/* ui_def_but_rna() sets non-array buttons to have a RNA index of 0. */
- but->custom_data = POINTER_FROM_INT((!is_array || is_expand) ? i : index);
+ decorator_but->rnaindex = (!is_array || is_expand) ? i : index;
}
}
@@ -3831,7 +3838,7 @@ static void ui_litem_layout_radial(uiLayout *litem)
bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
/* enable drawing as pie item if supported by widget */
if (ui_item_is_radial_drawable(bitem)) {
- bitem->but->dt = UI_EMBOSS_RADIAL;
+ bitem->but->emboss = UI_EMBOSS_RADIAL;
bitem->but->drawflag |= UI_BUT_ICON_LEFT;
}
}
@@ -4819,8 +4826,6 @@ void ui_layout_list_set_labels_active(uiLayout *layout)
uiLayout *uiLayoutListBox(uiLayout *layout,
uiList *ui_list,
- PointerRNA *ptr,
- PropertyRNA *prop,
PointerRNA *actptr,
PropertyRNA *actprop)
{
@@ -4829,8 +4834,6 @@ uiLayout *uiLayoutListBox(uiLayout *layout,
but->custom_data = ui_list;
- but->rnasearchpoin = *ptr;
- but->rnasearchprop = prop;
but->rnapoin = *actptr;
but->rnaprop = actprop;
@@ -5039,7 +5042,7 @@ float uiLayoutGetUnitsY(uiLayout *layout)
int uiLayoutGetEmboss(uiLayout *layout)
{
if (layout->emboss == UI_EMBOSS_UNDEFINED) {
- return layout->root->block->dt;
+ return layout->root->block->emboss;
}
return layout->emboss;
}
@@ -5407,6 +5410,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
else {
BLI_addtail(&layout->items, bitem);
}
+ but->layout = layout;
if (layout->context) {
but->context = layout->context;
@@ -5414,8 +5418,32 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
}
if (layout->emboss != UI_EMBOSS_UNDEFINED) {
- but->dt = layout->emboss;
+ but->emboss = layout->emboss;
+ }
+}
+
+bool ui_layout_replace_but_ptr(uiLayout *layout, const void *old_but_ptr, uiBut *new_but)
+{
+ ListBase *child_list = layout->child_items_layout ? &layout->child_items_layout->items :
+ &layout->items;
+
+ LISTBASE_FOREACH (uiItem *, item, child_list) {
+ if (item->type == ITEM_BUTTON) {
+ uiButtonItem *bitem = (uiButtonItem *)item;
+
+ if (bitem->but == old_but_ptr) {
+ bitem->but = new_but;
+ return true;
+ }
+ }
+ else {
+ if (ui_layout_replace_but_ptr((uiLayout *)item, old_but_ptr, new_but)) {
+ return true;
+ }
+ }
}
+
+ return false;
}
void uiLayoutSetFixedSize(uiLayout *layout, bool fixed_size)
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 39c1b8bb909..5a49f3e70d0 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1148,10 +1148,11 @@ static bool jump_to_target_button(bContext *C, bool poll)
/* For string properties with prop_search, look up the search collection item. */
if (type == PROP_STRING) {
const uiBut *but = UI_context_active_but_get(C);
+ const uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but :
+ NULL;
- if (but->type == UI_BTYPE_SEARCH_MENU && but->search &&
- but->search->update_fn == ui_rna_collection_search_update_fn) {
- uiRNACollectionSearch *coll_search = but->search->arg;
+ if (search_but && search_but->items_update_fn == ui_rna_collection_search_update_fn) {
+ uiRNACollectionSearch *coll_search = search_but->arg;
char str_buf[MAXBONENAME];
char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL);
@@ -1807,7 +1808,7 @@ static void UI_OT_drop_color(wmOperatorType *ot)
ot->flag = OPTYPE_INTERNAL;
RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0);
- RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected ");
+ RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected");
}
/** \} */
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 4634f4b95c9..edb5d51a392 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -90,7 +90,7 @@ bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
if (but->flag & UI_SCROLLED) {
return false;
}
- if ((but->type == UI_BTYPE_TEXT) && (but->dt == UI_EMBOSS_NONE) && !labeledit) {
+ if ((but->type == UI_BTYPE_TEXT) && (but->emboss == UI_EMBOSS_NONE) && !labeledit) {
return false;
}
if ((but->type == UI_BTYPE_LISTROW) && labeledit) {
@@ -113,7 +113,7 @@ bool UI_but_is_utf8(const uiBut *but)
#ifdef USE_UI_POPOVER_ONCE
bool ui_but_is_popover_once_compat(const uiBut *but)
{
- return ((but->type == UI_BTYPE_BUT) || ui_but_is_toggle(but));
+ return (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR) || ui_but_is_toggle(but));
}
#endif
diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c
index 1f8af7b9e6e..1773a7b3057 100644
--- a/source/blender/editors/interface/interface_region_hud.c
+++ b/source/blender/editors/interface/interface_region_hud.c
@@ -367,7 +367,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area)
ED_area_update_region_sizes(wm, win, area);
}
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
ED_region_tag_redraw(region);
/* Reset zoom level (not well supported). */
diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c
index 2ad7e517c60..13c85952f52 100644
--- a/source/blender/editors/interface/interface_region_popup.c
+++ b/source/blender/editors/interface/interface_region_popup.c
@@ -759,7 +759,7 @@ uiBlock *ui_popup_block_refresh(bContext *C,
ui_popup_block_scrolltest(block);
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* get winmat now that we actually have the subwindow */
wmGetProjectionMatrix(block->winmat, &region->winrct);
diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c
index a9e87f4cc07..2010d89165e 100644
--- a/source/blender/editors/interface/interface_region_search.c
+++ b/source/blender/editors/interface/interface_region_search.c
@@ -302,8 +302,11 @@ bool ui_searchbox_inside(ARegion *region, int x, int y)
bool ui_searchbox_apply(uiBut *but, ARegion *region)
{
uiSearchboxData *data = region->regiondata;
+ uiButSearch *search_but = (uiButSearch *)but;
- but->func_arg2 = NULL;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
+ search_but->item_active = NULL;
if (data->active != -1) {
const char *name = data->items.names[data->active] +
@@ -316,7 +319,7 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
- but->func_arg2 = data->items.pointers[data->active];
+ search_but->item_active = data->items.pointers[data->active];
return true;
}
@@ -340,8 +343,13 @@ static struct ARegion *wm_searchbox_tooltip_init(struct bContext *C,
LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
- if (but->search && but->search->tooltip_fn) {
- return but->search->tooltip_fn(C, region, but->search->arg, but->func_arg2);
+ if (but->type != UI_BTYPE_SEARCH_MENU) {
+ continue;
+ }
+
+ uiButSearch *search_but = (uiButSearch *)but;
+ if (search_but->item_tooltip_fn) {
+ return search_but->item_tooltip_fn(C, region, search_but->arg, search_but->item_active);
}
}
}
@@ -352,10 +360,13 @@ bool ui_searchbox_event(
bContext *C, ARegion *region, uiBut *but, ARegion *butregion, const wmEvent *event)
{
uiSearchboxData *data = region->regiondata;
+ uiButSearch *search_but = (uiButSearch *)but;
int type = event->type, val = event->val;
bool handled = false;
bool tooltip_timer_started = false;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
if (type == MOUSEPAN) {
ui_pan_to_scroll(event, &type, &val);
}
@@ -373,7 +384,7 @@ bool ui_searchbox_event(
break;
case RIGHTMOUSE:
if (val) {
- if (but->search->context_menu_fn) {
+ if (search_but->item_context_menu_fn) {
if (data->active != -1) {
/* Check the cursor is over the active element
* (a little confusing if this isn't the case, although it does work). */
@@ -383,7 +394,7 @@ bool ui_searchbox_event(
&rect, event->x - region->winrct.xmin, event->y - region->winrct.ymin)) {
void *active = data->items.pointers[data->active];
- if (but->search->context_menu_fn(C, but->search->arg, active, event)) {
+ if (search_but->item_context_menu_fn(C, search_but->arg, active, event)) {
handled = true;
}
}
@@ -417,7 +428,7 @@ bool ui_searchbox_event(
if (is_inside) {
if (data->active != -1) {
ScrArea *area = CTX_wm_area(C);
- but->func_arg2 = data->items.pointers[data->active];
+ search_but->item_active = data->items.pointers[data->active];
WM_tooltip_timer_init(C, CTX_wm_window(C), area, butregion, wm_searchbox_tooltip_init);
tooltip_timer_started = true;
}
@@ -437,18 +448,24 @@ bool ui_searchbox_event(
}
/** Wrap #uiButSearchUpdateFn callback. */
-static void ui_searchbox_update_fn(bContext *C, uiBut *but, const char *str, uiSearchItems *items)
+static void ui_searchbox_update_fn(bContext *C,
+ uiButSearch *search_but,
+ const char *str,
+ uiSearchItems *items)
{
wmWindow *win = CTX_wm_window(C);
WM_tooltip_clear(C, win);
- but->search->update_fn(C, but->search->arg, str, items);
+ search_but->items_update_fn(C, search_but->arg, str, items);
}
/* region is the search box itself */
void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool reset)
{
+ uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
/* reset vars */
data->items.totitem = 0;
data->items.more = 0;
@@ -460,9 +477,9 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
data->active = -1;
/* handle active */
- if (but->search->update_fn && but->func_arg2) {
- data->items.active = but->func_arg2;
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ if (search_but->items_update_fn && search_but->item_active) {
+ data->items.active = search_but->item_active;
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
data->items.active = NULL;
/* found active item, calculate real offset by centering it */
@@ -491,8 +508,8 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
}
/* callback */
- if (but->search->update_fn) {
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ if (search_but->items_update_fn) {
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
}
/* handle case where editstr is equal to one of items */
@@ -523,13 +540,16 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
int ui_searchbox_autocomplete(bContext *C, ARegion *region, uiBut *but, char *str)
{
+ uiButSearch *search_but = (uiButSearch *)but;
uiSearchboxData *data = region->regiondata;
int match = AUTOCOMPLETE_NO_MATCH;
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
+
if (str[0]) {
data->items.autocpl = UI_autocomplete_begin(str, ui_but_string_get_max_length(but));
- ui_searchbox_update_fn(C, but, but->editstr, &data->items);
+ ui_searchbox_update_fn(C, search_but, but->editstr, &data->items);
match = UI_autocomplete_end(data->items.autocpl, str);
data->items.autocpl = NULL;
@@ -673,10 +693,11 @@ static void ui_searchbox_region_free_cb(ARegion *region)
region->regiondata = NULL;
}
-ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
wmWindow *win = CTX_wm_window(C);
const uiStyle *style = UI_style_get();
+ uiBut *but = &search_but->but;
static ARegionType type;
ARegion *region;
uiSearchboxData *data;
@@ -725,7 +746,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
if (but->optype != NULL || (but->drawflag & UI_BUT_HAS_SHORTCUT) != 0) {
data->use_sep = true;
}
- data->sep_string = but->search->sep_string;
+ data->sep_string = search_but->item_sep_string;
/* compute position */
if (but->block->flag & UI_BLOCK_SEARCH_MENU) {
@@ -819,7 +840,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
}
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* notify change and redraw */
ED_region_tag_redraw(region);
@@ -945,12 +966,12 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe
}
}
-ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_operator(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
ARegion *region;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- region = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
+ region = ui_searchbox_create_generic(C, butregion, search_but);
region->type->draw = ui_searchbox_region_draw_cb__operator;
@@ -967,12 +988,12 @@ static void ui_searchbox_region_draw_cb__menu(const bContext *UNUSED(C), ARegion
/* Currently unused. */
}
-ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but)
+ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiButSearch *search_but)
{
ARegion *region;
- UI_but_drawflag_enable(but, UI_BUT_HAS_SHORTCUT);
- region = ui_searchbox_create_generic(C, butregion, but);
+ UI_but_drawflag_enable(&search_but->but, UI_BUT_HAS_SHORTCUT);
+ region = ui_searchbox_create_generic(C, butregion, search_but);
if (false) {
region->type->draw = ui_searchbox_region_draw_cb__menu;
@@ -983,8 +1004,9 @@ ARegion *ui_searchbox_create_menu(bContext *C, ARegion *butregion, uiBut *but)
/* sets red alert if button holds a string it can't find */
/* XXX weak: search_func adds all partial matches... */
-void ui_but_search_refresh(uiBut *but)
+void ui_but_search_refresh(uiButSearch *search_but)
{
+ uiBut *but = &search_but->but;
uiSearchItems *items;
int x1;
@@ -1004,7 +1026,7 @@ void ui_but_search_refresh(uiBut *but)
items->names[x1] = MEM_callocN(but->hardmax + 1, "search names");
}
- ui_searchbox_update_fn(but->block->evil_C, but, but->drawstr, items);
+ ui_searchbox_update_fn(but->block->evil_C, search_but, but->drawstr, items);
/* only redalert when we are sure of it, this can miss cases when >10 matches */
if (items->totitem == 0) {
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 46814e11b9e..41b41cb3d75 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, "")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
expr_result = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) {
if (STREQ(expr_result, ".")) {
MEM_freeN(expr_result);
expr_result = NULL;
@@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
shortcut = BLI_strdup(has_valid_context_error);
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
wmKeyMap *keymap = (wmKeyMap *)expr_result;
LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) {
@@ -659,7 +659,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
/* pass */
}
else if (BPY_execute_string_as_string_and_size(
- C, expr_imports, expr, true, &expr_result, &expr_result_len)) {
+ C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) {
/* pass. */
}
}
@@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (has_valid_context == false) {
/* pass */
}
- else if (BPY_execute_string_as_intptr(C, expr_imports, expr, true, &expr_result)) {
+ else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) {
if (expr_result != 0) {
{
uiTooltipField *field = text_field_add(data,
@@ -1386,7 +1386,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C,
}
/* adds subwindow */
- ED_region_floating_initialize(region);
+ ED_region_floating_init(region);
/* notify change and redraw */
ED_region_tag_redraw(region);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index 64070725f2b..5310ff0e3ec 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -334,7 +334,7 @@ void UI_fontstyle_draw_simple_backdrop(const uiFontStyle *fs,
const float margin = height / 4.0f;
/* backdrop */
- float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f};
+ const float color[4] = {col_bg[0], col_bg[1], col_bg[2], 0.5f};
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(true,
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index d3487b635ce..c7d3d7bf501 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -5512,22 +5512,24 @@ void uiTemplatePalette(uiLayout *layout,
}
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &color_ptr);
- uiDefButR(block,
- UI_BTYPE_COLOR,
- 0,
- "",
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- &color_ptr,
- "color",
- -1,
- 0.0,
- 1.0,
- UI_PALETTE_COLOR,
- col_id,
- "");
+ uiButColor *color_but = (uiButColor *)uiDefButR(block,
+ UI_BTYPE_COLOR,
+ 0,
+ "",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &color_ptr,
+ "color",
+ -1,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ "");
+ color_but->is_pallete_color = true;
+ color_but->palette_color_index = col_id;
row_cols++;
col_id++;
}
@@ -6210,7 +6212,7 @@ void uiTemplateList(uiLayout *layout,
switch (layout_type) {
case UILST_LAYOUT_DEFAULT:
/* layout */
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
glob = uiLayoutColumn(box, true);
row = uiLayoutRow(glob, false);
col = uiLayoutColumn(row, true);
@@ -6348,7 +6350,7 @@ void uiTemplateList(uiLayout *layout,
}
break;
case UILST_LAYOUT_GRID:
- box = uiLayoutListBox(layout, ui_list, dataptr, prop, active_dataptr, activeprop);
+ box = uiLayoutListBox(layout, ui_list, active_dataptr, activeprop);
glob = uiLayoutColumn(box, true);
row = uiLayoutRow(glob, false);
col = uiLayoutColumn(row, true);
@@ -6789,22 +6791,24 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
struct ProgressTooltip_Store *tip_arg = MEM_mallocN(sizeof(*tip_arg), __func__);
tip_arg->wm = wm;
tip_arg->owner = owner;
- uiBut *but_progress = uiDefIconTextBut(block,
- UI_BTYPE_PROGRESS_BAR,
- 0,
- 0,
- text,
- UI_UNIT_X,
- 0,
- UI_UNIT_X * 6.0f,
- UI_UNIT_Y,
- NULL,
- 0.0f,
- 0.0f,
- progress,
- 0,
- NULL);
- UI_but_func_tooltip_set(but_progress, progress_tooltip_func, tip_arg);
+ uiButProgressbar *but_progress = (uiButProgressbar *)uiDefIconTextBut(block,
+ UI_BTYPE_PROGRESS_BAR,
+ 0,
+ 0,
+ text,
+ UI_UNIT_X,
+ 0,
+ UI_UNIT_X * 6.0f,
+ UI_UNIT_Y,
+ NULL,
+ 0.0f,
+ 0.0f,
+ 0.0f,
+ 0,
+ NULL);
+
+ but_progress->progress = progress;
+ UI_but_func_tooltip_set(&but_progress->but, progress_tooltip_func, tip_arg);
}
if (!wm->is_interface_locked) {
@@ -7348,6 +7352,9 @@ void uiTemplateCacheFile(uiLayout *layout,
uiItemR(row, &fileptr, "scale", 0, IFACE_("Manual Scale"), ICON_NONE);
}
+ uiItemR(layout, &fileptr, "velocity_name", 0, NULL, ICON_NONE);
+ uiItemR(layout, &fileptr, "velocity_unit", 0, NULL, ICON_NONE);
+
/* TODO: unused for now, so no need to expose. */
#if 0
row = uiLayoutRow(layout, false);
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 208fd7136da..4a1c7be918e 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -148,7 +148,7 @@ uiBut *uiDefAutoButR(uiBlock *block,
if (RNA_property_array_check(prop) && index == -1) {
if (ELEM(RNA_property_subtype(prop), PROP_COLOR, PROP_COLOR_GAMMA)) {
but = uiDefButR_prop(
- block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, -1, -1, NULL);
+ block, UI_BTYPE_COLOR, 0, name, x1, y1, x2, y2, ptr, prop, -1, 0, 0, 0, 0, NULL);
}
else {
return NULL;
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 9ba1a2c73f4..7c33c5e7048 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -518,7 +518,7 @@ GPUBatch *ui_batch_roundbox_shadow_get(void)
void UI_draw_anti_tria(
float x1, float y1, float x2, float y2, float x3, float y3, const float color[4])
{
- float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
+ const float tri_arr[3][2] = {{x1, y1}, {x2, y2}, {x3, y3}};
float draw_color[4];
copy_v4_v4(draw_color, color);
@@ -1356,7 +1356,7 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
static int ui_but_draw_menu_icon(const uiBut *but)
{
- return (but->flag & UI_BUT_ICON_SUBMENU) && (but->dt == UI_EMBOSS_PULLDOWN);
+ return (but->flag & UI_BUT_ICON_SUBMENU) && (but->emboss == UI_EMBOSS_PULLDOWN);
}
/* icons have been standardized... and this call draws in untransformed coordinates */
@@ -1400,7 +1400,7 @@ static void widget_draw_icon(
alpha *= but->a2;
}
}
- else if (ELEM(but->type, UI_BTYPE_BUT)) {
+ else if (ELEM(but->type, UI_BTYPE_BUT, UI_BTYPE_DECORATOR)) {
if (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
alpha *= 0.5f;
}
@@ -1417,7 +1417,7 @@ static void widget_draw_icon(
but->str && but->str[0] == '\0') {
xs = rect->xmin + 2.0f * ofs;
}
- else if (but->dt == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
+ else if (but->emboss == UI_EMBOSS_NONE || but->type == UI_BTYPE_LABEL) {
xs = rect->xmin + 2.0f * ofs;
}
else {
@@ -2375,7 +2375,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
/* pass (even if its a menu toolbar) */
}
else if (ui_block_is_pie_menu(but->block)) {
- if (but->dt == UI_EMBOSS_RADIAL) {
+ if (but->emboss == UI_EMBOSS_RADIAL) {
rect->xmin += 0.3f * U.widget_unit;
}
}
@@ -2568,7 +2568,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag)
}
if (state & UI_BUT_REDALERT) {
- uchar red[4] = {255, 0, 0};
+ const uchar red[4] = {255, 0, 0};
if (wt->draw) {
color_blend_v3_v3(wt->wcol.inner, red, 0.4f);
}
@@ -2585,7 +2585,7 @@ static void widget_state(uiWidgetType *wt, int state, int drawflag)
}
if (state & UI_BUT_NODE_ACTIVE) {
- uchar blue[4] = {86, 128, 194};
+ const uchar blue[4] = {86, 128, 194};
color_blend_v3_v3(wt->wcol.inner, blue, 0.3f);
}
}
@@ -3609,6 +3609,7 @@ static void widget_scroll(
static void widget_progressbar(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign)
{
+ uiButProgressbar *but_progressbar = (uiButProgressbar *)but;
uiWidgetBase wtb, wtb_bar;
rcti rect_prog = *rect, rect_bar = *rect;
@@ -3616,7 +3617,7 @@ static void widget_progressbar(
widget_init(&wtb_bar);
/* round corners */
- float value = but->a1;
+ float value = but_progressbar->progress;
float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog);
float w = value * BLI_rcti_size_x(&rect_prog);
@@ -3768,6 +3769,8 @@ static void widget_numslider(
static void widget_swatch(
uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
{
+ BLI_assert(but->type == UI_BTYPE_COLOR);
+ uiButColor *color_but = (uiButColor *)but;
uiWidgetBase wtb;
float rad, col[4];
@@ -3822,8 +3825,8 @@ static void widget_swatch(
}
widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers);
- if (but->a1 == UI_PALETTE_COLOR &&
- ((Palette *)but->rnapoin.owner_id)->active_color == (int)but->a2) {
+ if (color_but->is_pallete_color &&
+ ((Palette *)but->rnapoin.owner_id)->active_color == color_but->palette_color_index) {
float width = rect->xmax - rect->xmin;
float height = rect->ymax - rect->ymin;
/* find color luminance and change it slightly */
@@ -4071,7 +4074,7 @@ static void widget_state_label(uiWidgetType *wt, int state, int drawflag)
}
if (state & UI_BUT_REDALERT) {
- uchar red[4] = {255, 0, 0};
+ const uchar red[4] = {255, 0, 0};
color_blend_v3_v3(wt->wcol.text, red, 0.4f);
}
}
@@ -4502,7 +4505,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
uiWidgetType *wt = NULL;
/* handle menus separately */
- if (but->dt == UI_EMBOSS_PULLDOWN) {
+ if (but->emboss == UI_EMBOSS_PULLDOWN) {
switch (but->type) {
case UI_BTYPE_LABEL:
widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect);
@@ -4515,7 +4518,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
}
}
- else if (but->dt == UI_EMBOSS_NONE) {
+ else if (but->emboss == UI_EMBOSS_NONE) {
/* "nothing" */
switch (but->type) {
case UI_BTYPE_LABEL:
@@ -4526,11 +4529,11 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
}
}
- else if (but->dt == UI_EMBOSS_RADIAL) {
+ else if (but->emboss == UI_EMBOSS_RADIAL) {
wt = widget_type(UI_WTYPE_MENU_ITEM_RADIAL);
}
else {
- BLI_assert(but->dt == UI_EMBOSS);
+ BLI_assert(but->emboss == UI_EMBOSS);
switch (but->type) {
case UI_BTYPE_LABEL:
@@ -4552,6 +4555,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
break;
case UI_BTYPE_BUT:
+ case UI_BTYPE_DECORATOR:
#ifdef USE_UI_TOOLBAR_HACK
if ((but->icon != ICON_NONE) && UI_but_is_tool(but)) {
wt = widget_type(UI_WTYPE_TOOLBAR_ITEM);
@@ -4779,7 +4783,7 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu
}
if (state & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) {
- if (but->dt != UI_EMBOSS_PULLDOWN) {
+ if (but->emboss != UI_EMBOSS_PULLDOWN) {
disabled = true;
}
}
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 0cbf73280a3..3efed43e08c 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -242,7 +242,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
bool tot_changed = false, do_init;
const uiStyle *style = UI_style_get();
- do_init = (v2d->flag & V2D_IS_INITIALISED) == 0;
+ do_init = (v2d->flag & V2D_IS_INIT) == 0;
/* see eView2D_CommonViewTypes in UI_view2d.h for available view presets */
switch (type) {
@@ -374,8 +374,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy)
break;
}
- /* set initialized flag so that View2D doesn't get reinitialised next time again */
- v2d->flag |= V2D_IS_INITIALISED;
+ /* set initialized flag so that View2D doesn't get reinitialized next time again */
+ v2d->flag |= V2D_IS_INIT;
/* store view size */
v2d->winx = winx;
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index 64cacd44e3d..d62058699d9 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -56,7 +56,7 @@ static bool view2d_poll(bContext *C)
{
ARegion *region = CTX_wm_region(C);
- return (region != NULL) && (region->v2d.flag & V2D_IS_INITIALISED);
+ return (region != NULL) && (region->v2d.flag & V2D_IS_INIT);
}
/** \} */
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 3786ed2789c..c617c921d70 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -735,7 +735,7 @@ void ED_mask_draw_region(
}
if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
- float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
float *buffer = mask_rasterize(mask_eval, width, height);
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
@@ -753,8 +753,7 @@ void ED_mask_draw_region(
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, 0.0f, 0.0f, width, height, GL_RED, GL_FLOAT, GL_NEAREST, buffer, 1.0f, 1.0f, NULL);
+ immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_R16F, false, buffer, 1.0f, 1.0f, NULL);
GPU_matrix_pop();
diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c
index 61b40dd3e60..dd4b8146154 100644
--- a/source/blender/editors/mesh/editmesh_bevel.c
+++ b/source/blender/editors/mesh/editmesh_bevel.c
@@ -1158,12 +1158,12 @@ void MESH_OT_bevel(wmOperatorType *ot)
PROFILE_HARD_MIN,
1.0f);
- prop = RNA_def_enum(ot->srna,
- "affect",
- prop_affect_items,
- BEVEL_AFFECT_EDGES,
- "Affect",
- "Affect Edges or Vertices");
+ RNA_def_enum(ot->srna,
+ "affect",
+ prop_affect_items,
+ BEVEL_AFFECT_EDGES,
+ "Affect",
+ "Affect Edges or Vertices");
RNA_def_boolean(ot->srna,
"clamp_overlap",
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c
index 9f1d499bb6a..6dde45a4f5f 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin.c
@@ -57,7 +57,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
{
ViewLayer *view_layer = CTX_data_view_layer(C);
float cent[3], axis[3];
- float d[3] = {0.0f, 0.0f, 0.0f};
+ const float d[3] = {0.0f, 0.0f, 0.0f};
RNA_float_get_array(op->ptr, "center", cent);
RNA_float_get_array(op->ptr, "axis", axis);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 347f6806d13..6f4f75e802a 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1628,9 +1628,9 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
plane_from_point_normal_v3(plane, v1, plane);
}
- /* First use bvh tree to find faces, knife edges, and knife verts that might
+ /* First use BVH tree to find faces, knife edges, and knife verts that might
* intersect the cut plane with rays v1-v3 and v2-v4.
- * This deduplicates the candidates before doing more expensive intersection tests. */
+ * This de-duplicates the candidates before doing more expensive intersection tests. */
tree = BKE_bmbvh_tree_get(kcd->bmbvh);
results = BLI_bvhtree_intersect_plane(tree, plane, &tot);
@@ -2632,7 +2632,7 @@ static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
{
- float mval[2] = {UNPACK2(mval_i)};
+ const float mval[2] = {UNPACK2(mval_i)};
knifetool_update_mval(kcd, mval);
}
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
index ed22d381a02..ef78d31a6bb 100644
--- a/source/blender/editors/mesh/editmesh_knife_project.c
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -164,7 +164,7 @@ void MESH_OT_knife_project(wmOperatorType *ot)
/* description */
ot->name = "Knife Project";
ot->idname = "MESH_OT_knife_project";
- ot->description = "Use other objects outlines & boundaries to project knife cuts";
+ ot->description = "Use other objects outlines and boundaries to project knife cuts";
/* callbacks */
ot->exec = knifeproject_exec;
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 89a90dcf12d..62c646a81e4 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -343,8 +343,11 @@ static BMVert *edbm_ripsel_edloop_pair_start_vert(BMEdge *e)
return (edbm_ripsel_edge_uid_step(e, &v_test)) ? e->v1 : e->v2;
}
-static void edbm_ripsel_deselect_helper(
- BMesh *bm, EdgeLoopPair *eloop_pairs, ARegion *region, float projectMat[4][4], float fmval[2])
+static void edbm_ripsel_deselect_helper(BMesh *bm,
+ EdgeLoopPair *eloop_pairs,
+ ARegion *region,
+ float projectMat[4][4],
+ const float fmval[2])
{
EdgeLoopPair *lp;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 1ea25353598..d2e9b57e950 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -205,7 +205,7 @@ static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint
/* -------------------------------------------------------------------- */
/** \name Find Nearest Vert/Edge/Face
*
- * \note Screen-space manhatten distances are used here,
+ * \note Screen-space manhattan distances are used here,
* since its faster and good enough for the purpose of selection.
*
* \note \a dist_bias is used so we can bias against selected items.
@@ -415,7 +415,7 @@ struct NearestEdgeUserData_Hit {
int index;
BMEdge *edge;
- /* edges only, un-biased manhatten distance to which ever edge we pick
+ /* edges only, un-biased manhattan distance to which ever edge we pick
* (not used for choosing) */
float dist_center;
};
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 4de7143682a..29860de88f1 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -7219,7 +7219,7 @@ void MESH_OT_wireframe(wmOperatorType *ot)
PropertyRNA *prop;
/* identifiers */
- ot->name = "Wire Frame";
+ ot->name = "Wireframe";
ot->idname = "MESH_OT_wireframe";
ot->description = "Create a solid wire-frame from faces";
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 9c364d41e24..81b8cd70353 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -205,7 +205,7 @@ void ED_object_rotation_from_quat(float rot[3], const float viewquat[4], const c
switch (align_axis) {
case 'X': {
/* Same as 'rv3d->viewinv[1]' */
- float axis_y[4] = {0.0f, 1.0f, 0.0f};
+ const float axis_y[4] = {0.0f, 1.0f, 0.0f};
float quat_y[4], quat[4];
axis_angle_to_quat(quat_y, axis_y, M_PI_2);
mul_qt_qtqt(quat, viewquat, quat_y);
@@ -692,6 +692,46 @@ void OBJECT_OT_lightprobe_add(wmOperatorType *ot)
* \{ */
/* for object add operator */
+
+static const char *get_effector_defname(ePFieldType type)
+{
+ switch (type) {
+ case PFIELD_FORCE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Force");
+ case PFIELD_VORTEX:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Vortex");
+ case PFIELD_MAGNET:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Magnet");
+ case PFIELD_WIND:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Wind");
+ case PFIELD_GUIDE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide");
+ case PFIELD_TEXTURE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "TextureField");
+ case PFIELD_HARMONIC:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Harmonic");
+ case PFIELD_CHARGE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Charge");
+ case PFIELD_LENNARDJ:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Lennard-Jones");
+ case PFIELD_BOID:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Boid");
+ case PFIELD_TURBULENCE:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Turbulence");
+ case PFIELD_DRAG:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Drag");
+ case PFIELD_FLUIDFLOW:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "FluidField");
+ case PFIELD_NULL:
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
+ case NUM_PFIELD_TYPES:
+ break;
+ }
+
+ BLI_assert(false);
+ return CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
+}
+
static int effector_add_exec(bContext *C, wmOperator *op)
{
Object *ob;
@@ -712,8 +752,8 @@ static int effector_add_exec(bContext *C, wmOperator *op)
if (type == PFIELD_GUIDE) {
Curve *cu;
- const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "CurveGuide");
- ob = ED_object_add_type(C, OB_CURVE, name, loc, rot, false, local_view_bits);
+ ob = ED_object_add_type(
+ C, OB_CURVE, get_effector_defname(type), loc, rot, false, local_view_bits);
cu = ob->data;
cu->flag |= CU_PATH | CU_3D;
@@ -726,8 +766,8 @@ static int effector_add_exec(bContext *C, wmOperator *op)
}
}
else {
- const char *name = CTX_DATA_(BLT_I18NCONTEXT_ID_OBJECT, "Field");
- ob = ED_object_add_type(C, OB_EMPTY, name, loc, rot, false, local_view_bits);
+ ob = ED_object_add_type(
+ C, OB_EMPTY, get_effector_defname(type), loc, rot, false, local_view_bits);
BKE_object_obdata_size_init(ob, dia);
if (ELEM(type, PFIELD_WIND, PFIELD_VORTEX)) {
ob->empty_drawtype = OB_SINGLE_ARROW;
@@ -1237,7 +1277,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
break;
}
- /* if this is a new object, initialise default stuff (colors, etc.) */
+ /* If this is a new object, initialize default stuff (colors, etc.) */
if (newob) {
/* set default viewport color to black */
copy_v3_fl(ob->color, 0.0f);
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index baa24ab2f4e..ae1aae27b7f 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -60,8 +60,6 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
-#include "GPU_draw.h" /* GPU_free_image */
-
#include "WM_api.h"
#include "WM_types.h"
@@ -530,7 +528,7 @@ static void multiresbake_freejob(void *bkv)
/* delete here, since this delete will be called from main thread */
for (link = data->images.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
MEM_freeN(data->ob_image.array);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index c4cb21a67f3..cb92fab3cb0 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -68,8 +68,6 @@
#include "ED_screen.h"
#include "ED_uvedit.h"
-#include "GPU_draw.h"
-
#include "object_intern.h"
/* prototypes */
@@ -308,7 +306,7 @@ static void refresh_images(BakeImages *bake_images)
Image *ima = bake_images->data[i].image;
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
if (tile->ok == IMA_OK_LOADED) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
break;
}
@@ -675,7 +673,7 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
/*
* returns the total number of pixels
*/
-static size_t initialize_internal_images(BakeImages *bake_images, ReportList *reports)
+static size_t init_internal_images(BakeImages *bake_images, ReportList *reports)
{
int i;
size_t tot_size = 0;
@@ -830,7 +828,7 @@ static int bake(Render *re,
build_image_lookup(bmain, ob_low, &bake_images);
if (is_save_internal) {
- num_pixels = initialize_internal_images(&bake_images, reports);
+ num_pixels = init_internal_images(&bake_images, reports);
if (num_pixels == 0) {
goto cleanup;
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index e93bd8bd94e..8d6d2e3e31d 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -345,7 +345,8 @@ static bool object_modifier_remove(
object_remove_particle_system(bmain, scene, ob);
return true;
}
- else if (md->type == eModifierType_Softbody) {
+
+ if (md->type == eModifierType_Softbody) {
if (ob->soft) {
sbFree(ob);
ob->softflag = 0; /* TODO(Sybren): this should probably be moved into sbFree() */
@@ -888,12 +889,11 @@ int ED_object_modifier_copy(
BLI_insertlinkafter(&ob->modifiers, md, nmd);
return true;
}
- else {
- nmd = BKE_modifier_new(md->type);
- BKE_modifier_copydata(md, nmd);
- BLI_insertlinkafter(&ob->modifiers, md, nmd);
- BKE_modifier_unique_name(&ob->modifiers, nmd);
- }
+
+ nmd = BKE_modifier_new(md->type);
+ BKE_modifier_copydata(md, nmd);
+ BLI_insertlinkafter(&ob->modifiers, md, nmd);
+ BKE_modifier_unique_name(&ob->modifiers, nmd);
return 1;
}
@@ -1458,9 +1458,7 @@ static int modifier_apply_as_shapekey_invoke(bContext *C, wmOperator *op, const
if (edit_modifier_invoke_properties(C, op, event, &retval)) {
return modifier_apply_as_shapekey_exec(C, op);
}
- else {
- return retval;
- }
+ return retval;
}
static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED(C),
@@ -2813,7 +2811,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
/* make a copy of ocean to use for baking - threadsafety */
ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(ocean, omd);
+ BKE_ocean_init_from_modifier(ocean, omd, omd->resolution);
#if 0
BKE_ocean_bake(ocean, och);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 9520b03f3a6..f4de8f712c8 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2283,7 +2283,8 @@ static int make_override_library_invoke(bContext *C, wmOperator *op, const wmEve
/* This invoke just calls another instance of this operator... */
return OPERATOR_INTERFACE;
}
- else if (ID_IS_LINKED(obact)) {
+
+ if (ID_IS_LINKED(obact)) {
/* Show menu with list of directly linked collections containing the active object. */
WM_enum_search_invoke(C, op, event);
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c
index 8981851394d..8d8f01dd61a 100644
--- a/source/blender/editors/object/object_remesh.c
+++ b/source/blender/editors/object/object_remesh.c
@@ -72,7 +72,6 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -407,7 +406,7 @@ static int voxel_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *eve
return OPERATOR_FINISHED;
}
- float mval[2] = {event->mval[0], event->mval[1]};
+ const float mval[2] = {event->mval[0], event->mval[1]};
float d = cd->init_mval[0] - mval[0];
@@ -471,7 +470,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
BoundBox *bb = BKE_mesh_boundbox_get(cd->active_object);
/* Indices of the Bounding Box faces. */
- int BB_faces[6][4] = {
+ const int BB_faces[6][4] = {
{3, 0, 4, 7},
{1, 2, 6, 5},
{3, 2, 1, 0},
@@ -526,7 +525,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev
float d_a[3], d_b[3];
float d_a_proj[2], d_b_proj[2];
float preview_plane_proj[4][3];
- float y_axis_proj[2] = {0.0f, 1.0f};
+ const float y_axis_proj[2] = {0.0f, 1.0f};
mid_v3_v3v3(text_pos, cd->preview_plane[0], cd->preview_plane[2]);
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index f2d7ad3ac11..52b572fb0dd 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1907,7 +1907,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const
for (int x = -ofs; x <= ofs; x += ofs / 2) {
for (int y = -ofs; y <= ofs; y += ofs / 2) {
if (x != 0 && y != 0) {
- int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y};
+ const int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y};
float n[3];
if (ED_view3d_depth_read_cached_normal(&xfd->vc, mval_ofs, n)) {
add_v3_v3(normal, n);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 749c6cd640e..82a1139c860 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4346,7 +4346,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
}
pa->size = 1.0f;
- initialize_particle(&sim, pa);
+ init_particle(&sim, pa);
reset_particle(&sim, pa, 0.0, 1.0);
point->flag |= PEP_EDIT_RECALC;
if (pe_x_mirror(ob)) {
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 673df69bf9b..d279958df8a 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -79,7 +79,6 @@
#include "RNA_define.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "render_intern.h"
@@ -351,7 +350,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
G.f &= ~G_FLAG_RENDER_VIEWPORT;
gp_rect = MEM_mallocN(sizex * sizey * sizeof(uchar) * 4, "offscreen rect");
- GPU_offscreen_read_pixels(oglrender->ofs, GL_UNSIGNED_BYTE, gp_rect);
+ GPU_offscreen_read_pixels(oglrender->ofs, GPU_DATA_UNSIGNED_BYTE, gp_rect);
for (i = 0; i < sizex * sizey * 4; i += 4) {
blend_color_mix_byte(&render_rect[i], &render_rect[i], &gp_rect[i]);
@@ -963,7 +962,7 @@ static void screen_opengl_render_cancel(bContext *C, wmOperator *op)
}
/* share between invoke and exec */
-static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
+static bool screen_opengl_render_anim_init(bContext *C, wmOperator *op)
{
/* initialize animation */
OGLRender *oglrender;
@@ -1257,7 +1256,7 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven
}
if (anim) {
- if (!screen_opengl_render_anim_initialize(C, op)) {
+ if (!screen_opengl_render_anim_init(C, op)) {
return OPERATOR_CANCELLED;
}
}
@@ -1293,7 +1292,7 @@ static int screen_opengl_render_exec(bContext *C, wmOperator *op)
bool ret = true;
- if (!screen_opengl_render_anim_initialize(C, op)) {
+ if (!screen_opengl_render_anim_init(C, op)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 19e4f652963..85fc6927063 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -82,7 +82,6 @@
#include "BIF_glutil.h"
-#include "GPU_glew.h"
#include "GPU_shader.h"
#include "RE_engine.h"
@@ -632,18 +631,8 @@ static bool ed_preview_draw_rect(ScrArea *area, int split, int first, rcti *rect
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state,
- fx,
- fy,
- rres.rectx,
- rres.recty,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- rect_byte,
- 1.0f,
- 1.0f,
- NULL);
+ immDrawPixelsTex(
+ &state, fx, fy, rres.rectx, rres.recty, GPU_RGBA8, false, rect_byte, 1.0f, 1.0f, NULL);
MEM_freeN(rect_byte);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index f87f631c643..58fb934ebf0 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -291,7 +291,7 @@ static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *a
/* Workaround for different color spaces between normal areas and the ones using GPUViewports. */
float alpha = WM_region_use_viewport(area, region) ? 0.6f : 0.4f;
- float color[4] = {0.05f, 0.05f, 0.05f, alpha};
+ const float color[4] = {0.05f, 0.05f, 0.05f, alpha};
UI_draw_roundbox_aa(
true, (float)az->x1, (float)az->y1, (float)az->x2, (float)az->y2, 4.0f, color);
@@ -813,7 +813,7 @@ void ED_workspace_status_text(bContext *C, const char *str)
/* ************************************************************ */
-static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea *area)
+static void area_azone_init(wmWindow *win, const bScreen *screen, ScrArea *area)
{
AZone *az;
@@ -883,7 +883,7 @@ static void area_azone_initialize(wmWindow *win, const bScreen *screen, ScrArea
}
}
-static void fullscreen_azone_initialize(ScrArea *area, ARegion *region)
+static void fullscreen_azone_init(ScrArea *area, ARegion *region)
{
AZone *az;
@@ -1007,10 +1007,10 @@ static bool region_azone_edge_poll(const ARegion *region, const bool is_fullscre
return true;
}
-static void region_azone_edge_initialize(ScrArea *area,
- ARegion *region,
- AZEdge edge,
- const bool is_fullscreen)
+static void region_azone_edge_init(ScrArea *area,
+ ARegion *region,
+ AZEdge edge,
+ const bool is_fullscreen)
{
AZone *az = NULL;
const bool is_hidden = (region->flag & (RGN_FLAG_HIDDEN | RGN_FLAG_TOO_SMALL));
@@ -1033,9 +1033,9 @@ static void region_azone_edge_initialize(ScrArea *area,
}
}
-static void region_azone_scrollbar_initialize(ScrArea *area,
- ARegion *region,
- AZScrollDirection direction)
+static void region_azone_scrollbar_init(ScrArea *area,
+ ARegion *region,
+ AZScrollDirection direction)
{
rcti scroller_vert = (direction == AZ_SCROLL_VERT) ? region->v2d.vert : region->v2d.hor;
AZone *az = MEM_callocN(sizeof(*az), __func__);
@@ -1061,16 +1061,16 @@ static void region_azone_scrollbar_initialize(ScrArea *area,
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-static void region_azones_scrollbars_initialize(ScrArea *area, ARegion *region)
+static void region_azones_scrollbars_init(ScrArea *area, ARegion *region)
{
const View2D *v2d = &region->v2d;
if ((v2d->scroll & V2D_SCROLL_VERTICAL) && ((v2d->scroll & V2D_SCROLL_VERTICAL_HANDLES) == 0)) {
- region_azone_scrollbar_initialize(area, region, AZ_SCROLL_VERT);
+ region_azone_scrollbar_init(area, region, AZ_SCROLL_VERT);
}
if ((v2d->scroll & V2D_SCROLL_HORIZONTAL) &&
((v2d->scroll & V2D_SCROLL_HORIZONTAL_HANDLES) == 0)) {
- region_azone_scrollbar_initialize(area, region, AZ_SCROLL_HOR);
+ region_azone_scrollbar_init(area, region, AZ_SCROLL_HOR);
}
}
@@ -1083,16 +1083,16 @@ static void region_azones_add_edge(ScrArea *area,
/* edge code (t b l r) is along which area edge azone will be drawn */
if (alignment == RGN_ALIGN_TOP) {
- region_azone_edge_initialize(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_BOTTOM_TO_TOPLEFT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_BOTTOM) {
- region_azone_edge_initialize(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_TOP_TO_BOTTOMRIGHT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_RIGHT) {
- region_azone_edge_initialize(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_LEFT_TO_TOPRIGHT, is_fullscreen);
}
else if (alignment == RGN_ALIGN_LEFT) {
- region_azone_edge_initialize(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
+ region_azone_edge_init(area, region, AE_RIGHT_TO_TOPLEFT, is_fullscreen);
}
}
@@ -1116,10 +1116,10 @@ static void region_azones_add(const bScreen *screen, ScrArea *area, ARegion *reg
}
if (is_fullscreen) {
- fullscreen_azone_initialize(area, region);
+ fullscreen_azone_init(area, region);
}
- region_azones_scrollbars_initialize(area, region);
+ region_azones_scrollbars_init(area, region);
}
/* dir is direction to check, not the splitting edge direction! */
@@ -1828,7 +1828,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
region_rect_recursive(area, area->regionbase.first, &rect, &overlap_rect, 0);
/* Dynamically sized regions may have changed region sizes, so we have to force azone update. */
- area_azone_initialize(win, screen, area);
+ area_azone_init(win, screen, area);
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
region_subwindow(region);
@@ -1847,7 +1847,7 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar
}
/* called in screen_refresh, or screens_init, also area size changes */
-void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area)
+void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area)
{
WorkSpace *workspace = WM_window_get_active_workspace(win);
const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
@@ -1890,7 +1890,7 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *area)
}
/* clear all azones, add the area triangle widgets */
- area_azone_initialize(win, screen, area);
+ area_azone_init(win, screen, area);
/* region windows, default and own handlers */
for (region = area->regionbase.first; region; region = region->next) {
@@ -1944,7 +1944,7 @@ void ED_region_update_rect(ARegion *region)
}
/* externally called for floating regions like menus */
-void ED_region_floating_initialize(ARegion *region)
+void ED_region_floating_init(ARegion *region)
{
BLI_assert(region->alignment == RGN_ALIGN_FLOAT);
@@ -1980,7 +1980,7 @@ void ED_region_visibility_change_update(bContext *C, ScrArea *area, ARegion *reg
WM_event_remove_handlers(C, &region->handlers);
}
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), area);
+ ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), area);
ED_area_tag_redraw(area);
}
@@ -2066,8 +2066,8 @@ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2)
ED_area_data_copy(tmp, sa1, false);
ED_area_data_copy(sa1, sa2, true);
ED_area_data_copy(sa2, tmp, true);
- ED_area_initialize(CTX_wm_manager(C), win, sa1);
- ED_area_initialize(CTX_wm_manager(C), win, sa2);
+ ED_area_init(CTX_wm_manager(C), win, sa1);
+ ED_area_init(CTX_wm_manager(C), win, sa2);
BKE_screen_area_free(tmp);
MEM_freeN(tmp);
@@ -2126,7 +2126,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
area->spacetype = type;
area->type = st;
- /* If st->new may be called, don't use context until then. The
+ /* If st->create may be called, don't use context until then. The
* area->type->context() callback has changed but data may be invalid
* (e.g. with properties editor) until space-data is properly created */
@@ -2166,7 +2166,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
if (st) {
/* Don't get scene from context here which may depend on space-data. */
Scene *scene = WM_window_get_active_scene(win);
- sl = st->new (area, scene);
+ sl = st->create(area, scene);
BLI_addhead(&area->spacedata, sl);
/* swap regions */
@@ -2204,7 +2204,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi
}
}
- ED_area_initialize(CTX_wm_manager(C), win, area);
+ ED_area_init(CTX_wm_manager(C), win, area);
/* tell WM to refresh, cursor types etc */
WM_event_add_mousemove(win);
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 5c3b1944164..05eac574d9d 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -95,9 +95,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
@@ -107,29 +106,38 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
float clip_max_y,
float xzoom,
float yzoom,
- float color[4])
+ const float color[4])
{
int subpart_x, subpart_y, tex_w = 256, tex_h = 256;
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
int components;
const bool use_clipping = ((clip_min_x < clip_max_x) && (clip_min_y < clip_max_y));
- float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
- if (type != GL_FLOAT) {
- BLI_assert(type == GL_UNSIGNED_BYTE);
- type = GL_UNSIGNED_BYTE;
+ if (ELEM(gpu_format, GPU_RGBA8, GPU_RGBA16F)) {
+ components = 4;
+ }
+ else if (ELEM(gpu_format, GPU_RGB16F)) {
+ components = 3;
+ }
+ else if (ELEM(gpu_format, GPU_R8, GPU_R16F)) {
+ components = 1;
+ }
+ else {
+ BLI_assert(!"Incompatible format passed to immDrawPixels");
+ return;
}
- eGPUTextureFormat gpu_format = (type == GL_FLOAT) ? GPU_RGBA16F : GPU_RGBA8;
- eGPUDataFormat gpu_data = (type == GL_FLOAT) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
- GPUTexture *texture = GPU_texture_create_nD(
- tex_w, tex_h, 0, 2, NULL, gpu_format, gpu_data, 0, false, NULL);
+ const bool use_float_data = ELEM(gpu_format, GPU_RGBA16F, GPU_RGB16F, GPU_R16F);
+ eGPUDataFormat gpu_data = (use_float_data) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+ size_t stride = components * ((use_float_data) ? sizeof(float) : sizeof(uchar));
- /* TODO replace GL_NEAREST/LINEAR in callers. */
- GPU_texture_filter_mode(texture, (zoomfilter == GL_LINEAR));
- GPU_texture_wrap_mode(texture, false, true);
+ GPUTexture *tex = GPU_texture_create_2d(tex_w, tex_h, gpu_format, NULL, NULL);
- GPU_texture_bind(texture, 0);
+ GPU_texture_filter_mode(tex, use_filter);
+ GPU_texture_wrap_mode(tex, false, true);
+
+ GPU_texture_bind(tex, 0);
/* setup seamless 2=on, 0=off */
seamless = ((tex_w < img_w || tex_h < img_h) && tex_w > 2 && tex_h > 2) ? 2 : 0;
@@ -140,20 +148,6 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
- if (format == GL_RGBA) {
- components = 4;
- }
- else if (format == GL_RGB) {
- components = 3;
- }
- else if (format == GL_RED) {
- components = 1;
- }
- else {
- BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
- return;
- }
-
/* optional */
/* NOTE: Shader could be null for GLSL OCIO drawing, it is fine, since
* it does not need color.
@@ -199,26 +193,32 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
{
int src_y = subpart_y * offset_y;
int src_x = subpart_x * offset_x;
- size_t stride = components * ((type == GL_FLOAT) ? sizeof(float) : sizeof(uchar));
#define DATA(_y, _x) ((char *)rect + stride * ((size_t)(_y)*img_w + (_x)))
{
void *data = DATA(src_y, src_x);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, type, data);
+ GPU_texture_update_sub(tex, gpu_data, data, 0, 0, 0, subpart_w, subpart_h, 0);
}
/* Add an extra border of pixels so linear interpolation looks ok
* at edges of full image. */
if (subpart_w < tex_w) {
void *data = DATA(src_y, src_x + subpart_w - 1);
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, type, data);
+ const int offset[2] = {subpart_w, 0};
+ const int extent[2] = {1, subpart_h};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
if (subpart_h < tex_h) {
void *data = DATA(src_y + subpart_h - 1, src_x);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, type, data);
+ const int offset[2] = {0, subpart_h};
+ const int extent[2] = {subpart_w, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
+
if (subpart_w < tex_w && subpart_h < tex_h) {
void *data = DATA(src_y + subpart_h - 1, src_x + subpart_w - 1);
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, type, data);
+ const int offset[2] = {subpart_w, subpart_h};
+ const int extent[2] = {1, 1};
+ GPU_texture_update_sub(tex, gpu_data, data, UNPACK2(offset), 0, UNPACK2(extent), 0);
}
#undef DATA
}
@@ -253,8 +253,8 @@ void immDrawPixelsTexScaled_clipping(IMMDrawPixelsTexState *state,
immUnbindProgram();
}
- GPU_texture_unbind(texture);
- GPU_texture_free(texture);
+ GPU_texture_unbind(tex);
+ GPU_texture_free(tex);
/* Restore default. */
GPU_unpack_row_length_set(0);
@@ -265,24 +265,22 @@ void immDrawPixelsTexScaled(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float scaleX,
float scaleY,
float xzoom,
float yzoom,
- float color[4])
+ const float color[4])
{
immDrawPixelsTexScaled_clipping(state,
x,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
scaleX,
scaleY,
@@ -300,22 +298,20 @@ void immDrawPixelsTex(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float xzoom,
float yzoom,
- float color[4])
+ const float color[4])
{
immDrawPixelsTexScaled_clipping(state,
x,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -333,9 +329,8 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float y,
int img_w,
int img_h,
- int format,
- int type,
- int zoomfilter,
+ eGPUTextureFormat gpu_format,
+ bool use_filter,
void *rect,
float clip_min_x,
float clip_min_y,
@@ -343,16 +338,15 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
float clip_max_y,
float xzoom,
float yzoom,
- float color[4])
+ const float color[4])
{
immDrawPixelsTexScaled_clipping(state,
x,
y,
img_w,
img_h,
- format,
- type,
- zoomfilter,
+ gpu_format,
+ use_filter,
rect,
1.0f,
1.0f,
@@ -371,7 +365,7 @@ void immDrawPixelsTex_clipping(IMMDrawPixelsTexState *state,
void ED_draw_imbuf_clipping(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float clip_min_x,
@@ -421,13 +415,13 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
if (ok) {
if (ibuf->rect_float) {
- int format = 0;
+ eGPUTextureFormat format = 0;
if (ibuf->channels == 3) {
- format = GL_RGB;
+ format = GPU_RGB16F;
}
else if (ibuf->channels == 4) {
- format = GL_RGBA;
+ format = GPU_RGBA16F;
}
else {
BLI_assert(!"Incompatible number of channels for GLSL display");
@@ -440,8 +434,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
ibuf->x,
ibuf->y,
format,
- GL_FLOAT,
- zoomfilter,
+ use_filter,
ibuf->rect_float,
clip_min_x,
clip_min_y,
@@ -459,9 +452,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
ibuf->rect,
clip_min_x,
clip_min_y,
@@ -493,9 +485,8 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- zoomfilter,
+ GPU_RGBA8,
+ use_filter,
display_buffer,
clip_min_x,
clip_min_y,
@@ -513,7 +504,7 @@ void ED_draw_imbuf_clipping(ImBuf *ibuf,
void ED_draw_imbuf(ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
ColorManagedViewSettings *view_settings,
ColorManagedDisplaySettings *display_settings,
float zoom_x,
@@ -522,7 +513,7 @@ void ED_draw_imbuf(ImBuf *ibuf,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
0.0f,
@@ -537,7 +528,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ImBuf *ibuf,
float x,
float y,
- int zoomfilter,
+ bool use_filter,
float clip_min_x,
float clip_min_y,
float clip_max_x,
@@ -553,7 +544,7 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
ED_draw_imbuf_clipping(ibuf,
x,
y,
- zoomfilter,
+ use_filter,
view_settings,
display_settings,
clip_min_x,
@@ -565,9 +556,9 @@ void ED_draw_imbuf_ctx_clipping(const bContext *C,
}
void ED_draw_imbuf_ctx(
- const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter, float zoom_x, float zoom_y)
+ const bContext *C, ImBuf *ibuf, float x, float y, bool use_filter, float zoom_x, float zoom_y)
{
- ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, zoomfilter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
+ ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, use_filter, 0.0f, 0.0f, 0.0f, 0.0f, zoom_x, zoom_y);
}
int ED_draw_imbuf_method(ImBuf *ibuf)
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 7983ac889ef..c17a34f97b9 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -475,7 +475,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_id_pointer_set(result, &obpose->id);
}
return 1;
- return -1; /* found but not available */
}
if (CTX_data_equals(member, "sequences")) {
Editing *ed = BKE_sequencer_editing_get(scene, false);
diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c
index 1608e842376..40a452a5363 100644
--- a/source/blender/editors/screen/screen_draw.c
+++ b/source/blender/editors/screen/screen_draw.c
@@ -619,7 +619,7 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin
screen_preview_draw(screen, size_x, size_y);
- GPU_offscreen_read_pixels(offscreen, GL_UNSIGNED_BYTE, r_rect);
+ GPU_offscreen_read_pixels(offscreen, GPU_DATA_UNSIGNED_BYTE, r_rect);
GPU_offscreen_unbind(offscreen, true);
GPU_offscreen_free(offscreen);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index b6f210d7f13..62720d8ca37 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -516,7 +516,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
ED_screen_areas_iter (win, screen, area) {
/* set spacetype and region callbacks, calls init() */
/* sets subwindows for regions, adds handlers */
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
/* wake up animtimer */
@@ -536,7 +536,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
}
/* file read, set all screens, ... */
-void ED_screens_initialize(Main *bmain, wmWindowManager *wm)
+void ED_screens_init(Main *bmain, wmWindowManager *wm)
{
wmWindow *win;
@@ -897,7 +897,7 @@ static void screen_global_area_refresh(wmWindow *win,
else {
area = screen_area_create_with_geometry(&win->global_areas, rect, space_type);
SpaceType *stype = BKE_spacetype_from_id(space_type);
- SpaceLink *slink = stype->new (area, WM_window_get_active_scene(win));
+ SpaceLink *slink = stype->create(area, WM_window_get_active_scene(win));
area->regionbase = slink->regionbase;
@@ -985,39 +985,14 @@ void ED_screen_global_areas_refresh(wmWindow *win)
/* -------------------------------------------------------------------- */
/* Screen changing */
-static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen)
-{
- for (bScreen *screen_iter = bmain->screens.first; screen_iter;
- screen_iter = screen_iter->id.next) {
- if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) {
- ScrArea *area = screen_iter->areabase.first;
- if (area && area->full == screen) {
- return screen_iter;
- }
- }
- }
-
- return screen;
-}
-
/**
* \return the screen to activate.
* \warning The returned screen may not always equal \a screen_new!
*/
-bScreen *screen_change_prepare(
+void screen_change_prepare(
bScreen *screen_old, bScreen *screen_new, Main *bmain, bContext *C, wmWindow *win)
{
- /* validate screen, it's called with notifier reference */
- if (BLI_findindex(&bmain->screens, screen_new) == -1) {
- return NULL;
- }
-
- screen_new = screen_fullscreen_find_associated_normal_screen(bmain, screen_new);
-
- /* check for valid winid */
- if (!(screen_new->winid == 0 || screen_new->winid == win->winid)) {
- return NULL;
- }
+ BLI_assert(BLI_findindex(&bmain->screens, screen_new) != -1);
if (screen_old != screen_new) {
wmTimer *wt = screen_old->animtimer;
@@ -1038,11 +1013,7 @@ bScreen *screen_change_prepare(
if (wt) {
screen_new->animtimer = wt;
}
-
- return screen_new;
}
-
- return NULL;
}
void screen_change_update(bContext *C, wmWindow *win, bScreen *screen)
@@ -1075,12 +1046,20 @@ bool ED_screen_change(bContext *C, bScreen *screen)
{
Main *bmain = CTX_data_main(C);
wmWindow *win = CTX_wm_window(C);
+ WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
+ WorkSpaceLayout *layout = BKE_workspace_layout_find(workspace, screen);
bScreen *screen_old = CTX_wm_screen(C);
- bScreen *screen_new = screen_change_prepare(screen_old, screen, bmain, C, win);
- if (screen_new) {
- WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
- WM_window_set_active_screen(win, workspace, screen);
+ /* Get the actual layout/screen to be activated (guaranteed to be unused, even if that means
+ * having to duplicate an existing one). */
+ WorkSpaceLayout *layout_new = ED_workspace_screen_change_ensure_unused_layout(
+ bmain, workspace, layout, layout, win);
+ bScreen *screen_new = BKE_workspace_layout_screen_get(layout_new);
+
+ screen_change_prepare(screen_old, screen_new, bmain, C, win);
+
+ if (screen_old != screen_new) {
+ WM_window_set_active_screen(win, workspace, screen_new);
screen_change_update(C, win, screen_new);
return true;
diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h
index 21168a992b5..a5b5e222ae9 100644
--- a/source/blender/editors/screen/screen_intern.h
+++ b/source/blender/editors/screen/screen_intern.h
@@ -49,11 +49,11 @@ bScreen *screen_add(struct Main *bmain, const char *name, const rcti *rect);
void screen_data_copy(bScreen *to, bScreen *from);
void screen_new_activate_prepare(const wmWindow *win, bScreen *screen_new);
void screen_change_update(struct bContext *C, wmWindow *win, bScreen *screen);
-bScreen *screen_change_prepare(bScreen *screen_old,
- bScreen *screen_new,
- struct Main *bmain,
- struct bContext *C,
- wmWindow *win);
+void screen_change_prepare(bScreen *screen_old,
+ bScreen *screen_new,
+ struct Main *bmain,
+ struct bContext *C,
+ wmWindow *win);
ScrArea *area_split(
const wmWindow *win, bScreen *screen, ScrArea *area, char dir, float fac, int merge);
int screen_area_join(struct bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2);
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index fde1498bc5e..f4d36a15d30 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -5184,7 +5184,7 @@ static void region_blend_end(bContext *C, ARegion *region, const bool is_running
else {
if (rgi->hidden) {
rgi->region->flag |= rgi->hidden;
- ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), rgi->area);
+ ED_area_init(CTX_wm_manager(C), CTX_wm_window(C), rgi->area);
}
/* area decoration needs redraw in end */
ED_area_tag_redraw(rgi->area);
@@ -5215,7 +5215,7 @@ void ED_region_visibility_change_update_animated(bContext *C, ScrArea *area, ARe
/* blend in, reinitialize regions because it got unhidden */
if (rgi->hidden == 0) {
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
else {
WM_event_remove_handlers(C, &region->handlers);
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 478a0adfd9a..b20dc80d158 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -88,22 +88,15 @@ static void workspace_change_update(WorkSpace *workspace_new,
#endif
}
-static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
-{
- /* return false to stop the iterator if we've found a layout that can be activated */
- return workspace_layout_set_poll(layout) ? false : true;
-}
-
static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain,
WorkSpace *workspace_new,
wmWindow *win)
{
- /* ED_workspace_duplicate may have stored a layout to activate
- * once the workspace gets activated. */
WorkSpaceLayout *layout_old = WM_window_get_active_layout(win);
WorkSpaceLayout *layout_new;
- bScreen *screen_new;
+ /* ED_workspace_duplicate may have stored a layout to activate
+ * once the workspace gets activated. */
if (win->workspace_hook->temp_workspace_store) {
layout_new = win->workspace_hook->temp_layout_store;
}
@@ -113,20 +106,9 @@ static WorkSpaceLayout *workspace_change_get_new_layout(Main *bmain,
layout_new = workspace_new->layouts.first;
}
}
- screen_new = BKE_workspace_layout_screen_get(layout_new);
-
- if (screen_new->winid) {
- /* screen is already used, try to find a free one */
- WorkSpaceLayout *layout_temp = BKE_workspace_layout_iter_circular(
- workspace_new, layout_new, workspace_change_find_new_layout_cb, NULL, false);
- if (!layout_temp) {
- /* fallback solution: duplicate layout from old workspace */
- layout_temp = ED_workspace_layout_duplicate(bmain, workspace_new, layout_old, win);
- }
- layout_new = layout_temp;
- }
- return layout_new;
+ return ED_workspace_screen_change_ensure_unused_layout(
+ bmain, workspace_new, layout_new, layout_old, win);
}
/**
@@ -153,10 +135,7 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager
return false;
}
- screen_new = screen_change_prepare(screen_old, screen_new, bmain, C, win);
- if (BKE_workspace_layout_screen_get(layout_new) != screen_new) {
- layout_new = BKE_workspace_layout_find(workspace_new, screen_new);
- }
+ screen_change_prepare(screen_old, screen_new, bmain, C, win);
if (screen_new == NULL) {
return false;
diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c
index 0af81e0db21..8a36cffa1f1 100644
--- a/source/blender/editors/screen/workspace_layout_edit.c
+++ b/source/blender/editors/screen/workspace_layout_edit.c
@@ -160,6 +160,66 @@ bool ED_workspace_layout_delete(WorkSpace *workspace, WorkSpaceLayout *layout_ol
return false;
}
+static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
+{
+ /* return false to stop the iterator if we've found a layout that can be activated */
+ return workspace_layout_set_poll(layout) ? false : true;
+}
+
+static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen)
+{
+ for (bScreen *screen_iter = bmain->screens.first; screen_iter;
+ screen_iter = screen_iter->id.next) {
+ if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) {
+ ScrArea *area = screen_iter->areabase.first;
+ if (area && area->full == screen) {
+ return screen_iter;
+ }
+ }
+ }
+
+ return screen;
+}
+
+static bool screen_is_used_by_other_window(const wmWindow *win, const bScreen *screen)
+{
+ return BKE_screen_is_used(screen) && (screen->winid != win->winid);
+}
+
+/**
+ * Make sure there is a non-fullscreen layout to switch to that is not used yet by an other window.
+ * Needed for workspace or screen switching to ensure valid screens.
+ *
+ * \param layout_fallback_base: As last resort, this layout is duplicated and returned.
+ */
+WorkSpaceLayout *ED_workspace_screen_change_ensure_unused_layout(
+ Main *bmain,
+ WorkSpace *workspace,
+ WorkSpaceLayout *layout_new,
+ const WorkSpaceLayout *layout_fallback_base,
+ wmWindow *win)
+{
+ WorkSpaceLayout *layout_temp = layout_new;
+ bScreen *screen_temp = BKE_workspace_layout_screen_get(layout_new);
+
+ screen_temp = screen_fullscreen_find_associated_normal_screen(bmain, screen_temp);
+ layout_temp = BKE_workspace_layout_find(workspace, screen_temp);
+
+ if (screen_is_used_by_other_window(win, screen_temp)) {
+ /* Screen is already used, try to find a free one. */
+ layout_temp = BKE_workspace_layout_iter_circular(
+ workspace, layout_new, workspace_change_find_new_layout_cb, NULL, false);
+ screen_temp = layout_temp ? BKE_workspace_layout_screen_get(layout_temp) : NULL;
+
+ if (!layout_temp || screen_is_used_by_other_window(win, screen_temp)) {
+ /* Fallback solution: duplicate layout. */
+ layout_temp = ED_workspace_layout_duplicate(bmain, workspace, layout_fallback_base, win);
+ }
+ }
+
+ return layout_temp;
+}
+
static bool workspace_layout_cycle_iter_cb(const WorkSpaceLayout *layout, void *UNUSED(arg))
{
/* return false to stop iterator when we have found a layout to activate */
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index d0082769575..ba32b53a9e0 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -56,7 +56,6 @@
#include "DEG_depsgraph.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -456,7 +455,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
}
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
LoadTexData data = {
.br = br,
@@ -540,54 +539,6 @@ static int project_brush_radius(ViewContext *vc, float radius, const float locat
return 0;
}
-static bool sculpt_get_brush_geometry(bContext *C,
- ViewContext *vc,
- int x,
- int y,
- int *pixel_radius,
- float location[3],
- UnifiedPaintSettings *ups)
-{
- Scene *scene = CTX_data_scene(C);
- Paint *paint = BKE_paint_get_active_from_context(C);
- float mouse[2];
- bool hit = false;
-
- mouse[0] = x;
- mouse[1] = y;
-
- if (vc->obact->sculpt && vc->obact->sculpt->pbvh) {
- if (!ups->stroke_active) {
- hit = SCULPT_stroke_get_location(C, location, mouse);
- }
- else {
- hit = ups->last_hit;
- copy_v3_v3(location, ups->last_location);
- }
- }
-
- if (hit) {
- Brush *brush = BKE_paint_brush(paint);
-
- *pixel_radius = project_brush_radius(
- vc, BKE_brush_unprojected_radius_get(scene, brush), location);
-
- if (*pixel_radius == 0) {
- *pixel_radius = BKE_brush_size_get(scene, brush);
- }
-
- mul_m4_v3(vc->obact->obmat, location);
- }
- else {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- Brush *brush = BKE_paint_brush(&sd->paint);
-
- *pixel_radius = BKE_brush_size_get(scene, brush);
- }
-
- return hit;
-}
-
/* Draw an overlay that shows what effect the brush's texture will
* have on brush strength. */
static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups,
@@ -924,7 +875,7 @@ BLI_INLINE void draw_rect_point(uint pos,
imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy);
}
-BLI_INLINE void draw_bezier_handle_lines(uint pos, float sel_col[4], BezTriple *bez)
+BLI_INLINE void draw_bezier_handle_lines(uint pos, const float sel_col[4], BezTriple *bez)
{
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
GPU_line_width(3.0f);
@@ -1042,10 +993,10 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc)
/* Special actions taken when paint cursor goes over mesh */
/* TODO: sculpt only for now. */
-static void paint_cursor_on_hit(UnifiedPaintSettings *ups,
- Brush *brush,
- ViewContext *vc,
- const float location[3])
+static void paint_cursor_update_unprojected_radius(UnifiedPaintSettings *ups,
+ Brush *brush,
+ ViewContext *vc,
+ const float location[3])
{
float unprojected_radius, projected_radius;
@@ -1077,18 +1028,6 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups,
}
}
-static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush)
-{
- if (paint->flags & PAINT_SHOW_BRUSH) {
- if (ELEM(mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) &&
- brush->imagepaint_tool == PAINT_TOOL_FILL) {
- return true;
- }
- return false;
- }
- return true;
-}
-
static void cursor_draw_point_screen_space(const uint gpuattr,
const ARegion *region,
const float true_location[3],
@@ -1188,8 +1127,27 @@ static void cursor_draw_point_with_symmetry(const uint gpuattr,
}
}
-static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession *ss)
+static void sculpt_geometry_preview_lines_draw(const uint gpuattr,
+ Brush *brush,
+ const bool is_multires,
+ SculptSession *ss)
{
+ if (!(brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
+ return;
+ }
+
+ if (is_multires) {
+ return;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
+ return;
+ }
+
+ if (!ss->deform_modifiers_active) {
+ return;
+ }
+
immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f);
/* Cursor normally draws on top, but for this part we need depth tests. */
@@ -1215,30 +1173,21 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, SculptSession
static void SCULPT_layer_brush_height_preview_draw(const uint gpuattr,
const Brush *brush,
- const float obmat[4][4],
- const float location[3],
- const float normal[3],
const float rds,
const float line_width,
const float outline_col[3],
const float alpha)
{
- float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float quat[4];
- float height_preview_trans[3];
- copy_m4_m4(cursor_trans, obmat);
- madd_v3_v3v3fl(height_preview_trans, location, normal, brush->height);
- translate_m4(
- cursor_trans, height_preview_trans[0], height_preview_trans[1], height_preview_trans[2]);
- rotation_between_vecs_to_quat(quat, z_axis, normal);
- quat_to_mat4(cursor_rot, quat);
+ float cursor_trans[4][4];
+ unit_m4(cursor_trans);
+ translate_m4(cursor_trans, 0.0f, 0.0f, brush->height);
+ GPU_matrix_push();
GPU_matrix_mul(cursor_trans);
- GPU_matrix_mul(cursor_rot);
GPU_line_width(line_width);
immUniformColor3fvAlpha(outline_col, alpha * 0.5f);
imm_draw_circle_wire_3d(gpuattr, 0, 0, rds, 80);
+ GPU_matrix_pop();
}
static bool paint_use_2d_cursor(ePaintMode mode)
@@ -1249,428 +1198,668 @@ static bool paint_use_2d_cursor(ePaintMode mode)
return false;
}
-static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
+typedef enum PaintCursorDrawingType {
+ PAINT_CURSOR_CURVE,
+ PAINT_CURSOR_2D,
+ PAINT_CURSOR_3D,
+} PaintCursorDrawingType;
+
+typedef struct PaintCursorContext {
+ bContext *C;
+ ARegion *region;
+ wmWindow *win;
+ wmWindowManager *wm;
+ Depsgraph *depsgraph;
+ Scene *scene;
+ UnifiedPaintSettings *ups;
+ Brush *brush;
+ Paint *paint;
+ ePaintMode mode;
+ ViewContext vc;
+
+ /* Sculpt related data. */
+ Sculpt *sd;
+ SculptSession *ss;
+ int prev_active_vertex_index;
+ bool is_stroke_active;
+ bool is_cursor_over_mesh;
+ bool is_multires;
+ float radius;
+
+ /* 3D view cursor position and normal. */
+ float location[3];
+ float scene_space_location[3];
+ float normal[3];
+
+ /* Cursor main colors. */
+ float outline_col[3];
+ float outline_alpha;
+
+ /* GPU attribute for drawing. */
+ uint pos;
+
+ PaintCursorDrawingType cursor_type;
+
+ /* This variable is set after drawing the overlay, not on initialization. It can't be used for
+ * checking if alpha overlay is enabled before drawing it. */
+ bool alpha_overlay_drawn;
+
+ float zoomx;
+ int x, y;
+ float translation[2];
+
+ float final_radius;
+ int pixel_radius;
+
+} PaintCursorContext;
+
+static bool paint_cursor_context_init(bContext *C,
+ const int x,
+ const int y,
+ PaintCursorContext *pcontext)
{
ARegion *region = CTX_wm_region(C);
if (region && region->regiontype != RGN_TYPE_WINDOW) {
- return;
+ return false;
}
- const wmWindowManager *wm = CTX_wm_manager(C);
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- Scene *scene = CTX_data_scene(C);
- UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- Paint *paint = BKE_paint_get_active_from_context(C);
- Brush *brush = BKE_paint_brush(paint);
- ePaintMode mode = BKE_paintmode_get_active_from_context(C);
+ pcontext->C = C;
+ pcontext->region = region;
+ pcontext->wm = CTX_wm_manager(C);
+ pcontext->win = CTX_wm_window(C);
+ pcontext->depsgraph = CTX_data_depsgraph_pointer(C);
+ pcontext->scene = CTX_data_scene(C);
+ pcontext->ups = &pcontext->scene->toolsettings->unified_paint_settings;
+ pcontext->paint = BKE_paint_get_active_from_context(C);
+ pcontext->brush = BKE_paint_brush(pcontext->paint);
+ pcontext->mode = BKE_paintmode_get_active_from_context(C);
+
+ ED_view3d_viewcontext_init(C, &pcontext->vc, pcontext->depsgraph);
+
+ if (pcontext->brush->flag & BRUSH_CURVE) {
+ pcontext->cursor_type = PAINT_CURSOR_CURVE;
+ }
+ else if (paint_use_2d_cursor(pcontext->mode)) {
+ pcontext->cursor_type = PAINT_CURSOR_2D;
+ }
+ else {
+ pcontext->cursor_type = PAINT_CURSOR_3D;
+ }
- /* 2d or 3d painting? */
- const bool use_2d_cursor = paint_use_2d_cursor(mode);
+ pcontext->x = x;
+ pcontext->y = y;
+ pcontext->translation[0] = (float)x;
+ pcontext->translation[1] = (float)y;
- /* check that brush drawing is enabled */
- if (ommit_cursor_drawing(paint, mode, brush)) {
- return;
+ float zoomx, zoomy;
+ get_imapaint_zoom(C, &zoomx, &zoomy);
+ pcontext->zoomx = max_ff(zoomx, zoomy);
+ pcontext->final_radius = (BKE_brush_size_get(pcontext->scene, pcontext->brush) * zoomx);
+
+ /* There is currently no way to check if the direction is invertex before starting the stroke, so
+ * this does not reflect the state of the brush in the UI. */
+ if (((pcontext->ups->draw_inverted == 0) ^ ((pcontext->brush->flag & BRUSH_DIR_IN) == 0)) &&
+ BKE_brush_sculpt_has_secondary_color(pcontext->brush)) {
+ copy_v3_v3(pcontext->outline_col, pcontext->brush->sub_col);
+ }
+ else {
+ copy_v3_v3(pcontext->outline_col, pcontext->brush->add_col);
}
+ pcontext->outline_alpha = pcontext->brush->add_col[3];
- /* Can't use stroke vc here because this will be called during
- * mouse over too, not just during a stroke. */
- ViewContext vc;
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
+ Object *active_object = pcontext->vc.obact;
+ pcontext->ss = active_object ? active_object->sculpt : NULL;
- if (vc.rv3d && (vc.rv3d->rflag & RV3D_NAVIGATING)) {
- return;
- }
+ pcontext->is_stroke_active = pcontext->ups->stroke_active;
- /* Skip everything and draw brush here. */
- if (brush->flag & BRUSH_CURVE) {
- paint_draw_curve_cursor(brush, &vc);
- return;
+ return true;
+}
+
+static void paint_cursor_update_pixel_radius(PaintCursorContext *pcontext)
+{
+ if (pcontext->is_cursor_over_mesh) {
+ Brush *brush = BKE_paint_brush(pcontext->paint);
+ pcontext->pixel_radius = project_brush_radius(
+ &pcontext->vc,
+ BKE_brush_unprojected_radius_get(pcontext->scene, brush),
+ pcontext->location);
+
+ if (pcontext->pixel_radius == 0) {
+ pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
+ }
+
+ copy_v3_v3(pcontext->scene_space_location, pcontext->location);
+ mul_m4_v3(pcontext->vc.obact->obmat, pcontext->scene_space_location);
}
+ else {
+ Sculpt *sd = CTX_data_tool_settings(pcontext->C)->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
- float zoomx, zoomy;
- get_imapaint_zoom(C, &zoomx, &zoomy);
- zoomx = max_ff(zoomx, zoomy);
+ pcontext->pixel_radius = BKE_brush_size_get(pcontext->scene, brush);
+ }
+}
- /* Set various defaults. */
- const float *outline_col = brush->add_col;
- const float outline_alpha = brush->add_col[3];
- float translation[2] = {x, y};
- float final_radius = (BKE_brush_size_get(scene, brush) * zoomx);
+static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcontext)
+{
+ BLI_assert(pcontext->ss != NULL);
+ BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
+
+ bContext *C = pcontext->C;
+ SculptSession *ss = pcontext->ss;
+ Brush *brush = pcontext->brush;
+ Scene *scene = pcontext->scene;
+ UnifiedPaintSettings *ups = pcontext->ups;
+ ViewContext *vc = &pcontext->vc;
+ SculptCursorGeometryInfo gi;
+
+ const float mouse[2] = {
+ pcontext->x - pcontext->region->winrct.xmin,
+ pcontext->y - pcontext->region->winrct.ymin,
+ };
- /* Don't calculate rake angles while a stroke is active because the rake variables are global
- * and we may get interference with the stroke itself.
- * For line strokes, such interference is visible. */
+ /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to
+ * work correctly */
+ pcontext->prev_active_vertex_index = ss->active_vertex_index;
if (!ups->stroke_active) {
- paint_calculate_rake_rotation(ups, brush, translation);
+ pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update(
+ C, &gi, mouse, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
+ copy_v3_v3(pcontext->location, gi.location);
+ copy_v3_v3(pcontext->normal, gi.normal);
+ }
+ else {
+ pcontext->is_cursor_over_mesh = ups->last_hit;
+ copy_v3_v3(pcontext->location, ups->last_location);
}
- /* Draw overlay. */
- bool alpha_overlay_active = paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode);
+ paint_cursor_update_pixel_radius(pcontext);
- if (ups->draw_anchored) {
- final_radius = ups->anchored_size;
- copy_v2_fl2(translation,
- ups->anchored_initial_mouse[0] + region->winrct.xmin,
- ups->anchored_initial_mouse[1] + region->winrct.ymin);
+ if (BKE_brush_use_locked_size(scene, brush)) {
+ BKE_brush_size_set(scene, brush, pcontext->pixel_radius);
}
- /* Make lines pretty. */
- GPU_line_width(2.0f);
+ if (pcontext->is_cursor_over_mesh) {
+ paint_cursor_update_unprojected_radius(ups, brush, vc, pcontext->scene_space_location);
+ }
- /* TODO: also set blend mode? */
- GPU_blend(true);
+ pcontext->is_multires = ss->pbvh != NULL && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
- GPU_line_smooth(true);
+ pcontext->sd = CTX_data_tool_settings(pcontext->C)->sculpt;
+}
- if (use_2d_cursor) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+static void paint_update_mouse_cursor(PaintCursorContext *pcontext)
+{
+ WM_cursor_set(pcontext->win, WM_CURSOR_PAINT);
+}
- immUniformColor3fvAlpha(outline_col, outline_alpha);
+static void paint_draw_2D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+
+ /* Draw brush outline. */
+ if (pcontext->ups->stroke_active && BKE_brush_use_size_pressure(pcontext->brush)) {
+ imm_draw_circle_wire_2d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius * pcontext->ups->size_pressure_value,
+ 40);
+ /* Outer at half alpha. */
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
+ }
- /* Draw brush outline. */
- if (ups->stroke_active && BKE_brush_use_size_pressure(brush)) {
- imm_draw_circle_wire_2d(
- pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
- /* Outer at half alpha. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- }
+ GPU_line_width(1.0f);
+ imm_draw_circle_wire_2d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 40);
+
+}
+
+static void paint_draw_legacy_3D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+ GPU_line_width(1.0f);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 40);
+}
- GPU_line_width(1.0f);
- imm_draw_circle_wire_2d(pos, translation[0], translation[1], final_radius, 40);
+static void paint_draw_3D_view_inactive_brush_cursor(PaintCursorContext *pcontext)
+{
+ GPU_line_width(1.0f);
+ /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.8);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius,
+ 80);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.35f);
+ imm_draw_circle_wire_3d(pcontext->pos,
+ pcontext->translation[0],
+ pcontext->translation[1],
+ pcontext->final_radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f),
+ 80);
+}
+
+static void paint_cursor_update_object_space_radius(PaintCursorContext *pcontext)
+{
+ if (!BKE_brush_use_locked_size(pcontext->scene, pcontext->brush)) {
+ pcontext->radius = paint_calc_object_space_radius(
+ &pcontext->vc, pcontext->location, BKE_brush_size_get(pcontext->scene, pcontext->brush));
}
else {
- /* 3D Painting. */
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
-
- /* TODO: as sculpt and other paint modes are unified, this
- * special mode of drawing will go away. */
- Object *obact = vc.obact;
- SculptSession *ss = obact ? obact->sculpt : NULL;
- if ((mode == PAINT_MODE_SCULPT) && ss) {
- float location[3];
- int pixel_radius;
-
- /* Test if brush is over the mesh. */
- bool hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location, ups);
-
- if (BKE_brush_use_locked_size(scene, brush)) {
- BKE_brush_size_set(scene, brush, pixel_radius);
- }
+ pcontext->radius = BKE_brush_unprojected_radius_get(pcontext->scene, pcontext->brush);
+ }
+}
- /* Check if brush is subtracting, use different color then */
- /* TODO: no way currently to know state of pen flip or
- * invert key modifier without starting a stroke. */
- if (((ups->draw_inverted == 0) ^ ((brush->flag & BRUSH_DIR_IN) == 0)) &&
- BKE_brush_sculpt_has_secondary_color(brush)) {
- outline_col = brush->sub_col;
- }
+static void paint_cursor_drawing_setup_cursor_space(PaintCursorContext *pcontext)
+{
+ float cursor_trans[4][4], cursor_rot[4][4];
+ const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ float quat[4];
+ copy_m4_m4(cursor_trans, pcontext->vc.obact->obmat);
+ translate_m4(cursor_trans, pcontext->location[0], pcontext->location[1], pcontext->location[2]);
+ rotation_between_vecs_to_quat(quat, z_axis, pcontext->normal);
+ quat_to_mat4(cursor_rot, quat);
+ GPU_matrix_mul(cursor_trans);
+ GPU_matrix_mul(cursor_rot);
+}
+
+static void paint_cursor_draw_main_inactive_cursor(PaintCursorContext *pcontext)
+{
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+ GPU_line_width(2.0f);
+ imm_draw_circle_wire_3d(pcontext->pos, 0, 0, pcontext->radius, 80);
+
+ GPU_line_width(1.0f);
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha * 0.5f);
+ imm_draw_circle_wire_3d(
+ pcontext->pos, 0, 0, pcontext->radius * clamp_f(pcontext->brush->alpha, 0.0f, 1.0f), 80);
+}
+
+static void paint_cursor_pose_brush_segments_draw(PaintCursorContext *pcontext)
+{
+ SculptSession *ss = pcontext->ss;
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ GPU_line_width(2.0f);
- /* Only do if brush is over the mesh. */
- if (hit) {
- paint_cursor_on_hit(ups, brush, &vc, location);
+ immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2);
+ for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
+ immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_orig);
+ immVertex3fv(pcontext->pos, ss->pose_ik_chain_preview->segments[i].initial_head);
+ }
+
+ immEnd();
+}
+
+static void paint_cursor_pose_brush_origins_draw(PaintCursorContext *pcontext)
+{
+
+ SculptSession *ss = pcontext->ss;
+ immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
+ for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
+ cursor_draw_point_screen_space(pcontext->pos,
+ pcontext->region,
+ ss->pose_ik_chain_preview->segments[i].initial_orig,
+ pcontext->vc.obact->obmat,
+ 3);
+ }
+}
+
+static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext)
+{
+ Brush *brush = pcontext->brush;
+
+ /* 2D fallof is better represented with the default 2D cursor, there is no need to draw anything
+ * else. */
+ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
+
+ if (pcontext->alpha_overlay_drawn) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
+
+ if (!pcontext->is_cursor_over_mesh) {
+ paint_draw_3D_view_inactive_brush_cursor(pcontext);
+ return;
+ }
+
+ paint_cursor_update_object_space_radius(pcontext);
+
+ const bool update_previews = pcontext->prev_active_vertex_index !=
+ SCULPT_active_vertex_get(pcontext->ss);
+
+ /* Setup drawing. */
+ wmViewport(&pcontext->region->winrct);
+
+ /* Drawing of Cursor overlays in 2D screen space. */
+
+ /* Cursor location symmetry points. */
+
+ const float *active_vertex_co = SCULPT_active_vertex_co_get(pcontext->ss);
+ if (len_v3v3(active_vertex_co, pcontext->location) < pcontext->radius) {
+ immUniformColor3fvAlpha(pcontext->outline_col, pcontext->outline_alpha);
+ cursor_draw_point_with_symmetry(pcontext->pos,
+ pcontext->region,
+ active_vertex_co,
+ pcontext->sd,
+ pcontext->vc.obact,
+ pcontext->radius);
+ }
+
+ /* Pose brush updates and rotation origins. */
+
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ /* Just after switching to the Pose Brush, the active vertex can be the same and the
+ * cursor won't be tagged to update, so always initialize the preview chain if it is
+ * null before drawing it. */
+ SculptSession *ss = pcontext->ss;
+ if (update_previews || !ss->pose_ik_chain_preview) {
+ BKE_sculpt_update_object_for_edit(
+ pcontext->depsgraph, pcontext->vc.obact, true, false, false);
+
+ /* Free the previous pose brush preview. */
+ if (ss->pose_ik_chain_preview) {
+ SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview);
}
+
+ /* Generate a new pose brush preview from the current cursor location. */
+ ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init(
+ pcontext->sd, pcontext->vc.obact, ss, brush, pcontext->location, pcontext->radius);
}
- immUniformColor3fvAlpha(outline_col, outline_alpha);
+ /* Draw the pose brush rotation origins. */
+ paint_cursor_pose_brush_origins_draw(pcontext);
+ }
- if (ups->stroke_active && BKE_brush_use_size_pressure(brush) && mode != PAINT_MODE_SCULPT) {
- imm_draw_circle_wire_3d(
- pos, translation[0], translation[1], final_radius * ups->size_pressure_value, 40);
- /* Outer at half alpha. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- }
+ /* Setup 3D perspective drawing. */
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(pcontext->wm,
+ pcontext->win,
+ pcontext->depsgraph,
+ pcontext->scene,
+ pcontext->region,
+ CTX_wm_view3d(pcontext->C),
+ NULL,
+ NULL,
+ NULL);
- /* Only sculpt mode cursor for now. */
- /* Disable for PBVH_GRIDS. */
- bool is_multires = ss && ss->pbvh && BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
+ GPU_matrix_push();
+ GPU_matrix_mul(pcontext->vc.obact->obmat);
- SculptCursorGeometryInfo gi;
- float mouse[2] = {x - region->winrct.xmin, y - region->winrct.ymin};
- int prev_active_vertex_index = -1;
- bool is_cursor_over_mesh = false;
+ /* Drawing Cursor overlays in 3D object space. */
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX)) {
+ SCULPT_geometry_preview_lines_update(pcontext->C, pcontext->ss, pcontext->radius);
+ sculpt_geometry_preview_lines_draw(
+ pcontext->pos, pcontext->brush, pcontext->is_multires, pcontext->ss);
+ }
- /* Update the active vertex. */
- if ((mode == PAINT_MODE_SCULPT) && ss && !ups->stroke_active) {
- prev_active_vertex_index = ss->active_vertex_index;
- is_cursor_over_mesh = SCULPT_cursor_geometry_info_update(
- C, &gi, mouse, (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE));
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ paint_cursor_pose_brush_segments_draw(pcontext);
+ }
+
+ GPU_matrix_pop();
+
+ /* Drawing Cursor overlays in Paint Cursor space (as additional info on top of the brush cursor)
+ */
+ GPU_matrix_push();
+ paint_cursor_drawing_setup_cursor_space(pcontext);
+ /* Main inactive cursor. */
+ paint_cursor_draw_main_inactive_cursor(pcontext);
+
+ /* Cloth brush local simulation areas. */
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
+ brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ const float white[3] = {1.0f, 1.0f, 1.0f};
+ const float zero_v[3] = {0.0f};
+ /* This functions sets its own drawing space in order to draw the simulation limits when the
+ * cursor is active. When used here, this cursor overlay is already in cursor space, so its
+ * position and normal should be set to 0. */
+ SCULPT_cloth_simulation_limits_draw(
+ pcontext->pos, brush, zero_v, zero_v, pcontext->radius, 1.0f, white, 0.25f);
+ }
+
+ /* Layer brush height. */
+ if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+ SCULPT_layer_brush_height_preview_draw(pcontext->pos,
+ brush,
+ pcontext->radius,
+ 1.0f,
+ pcontext->outline_col,
+ pcontext->outline_alpha);
+ }
+
+ GPU_matrix_pop();
+
+ /* Reset drawing. */
+ GPU_matrix_pop_projection();
+ wmWindowViewport(pcontext->win);
+}
+
+static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorContext *pcontext)
+{
+ BLI_assert(pcontext->ss != NULL);
+ BLI_assert(pcontext->mode == PAINT_MODE_SCULPT);
+
+ SculptSession *ss = pcontext->ss;
+ Brush *brush = pcontext->brush;
+
+ /* The cursor can be updated as active before creating the StrokeCache, so this needs to be
+ * checked. */
+ if (!ss->cache) {
+ return;
+ }
+
+ /* Most of the brushes initialize the necessary data for the custom cursor drawing after the
+ * first brush step, so make sure that it is not drawn before being initialized. */
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ return;
+ }
+
+ /* Setup drawing. */
+ wmViewport(&pcontext->region->winrct);
+ GPU_matrix_push_projection();
+ ED_view3d_draw_setup_view(pcontext->wm,
+ pcontext->win,
+ pcontext->depsgraph,
+ pcontext->scene,
+ pcontext->region,
+ CTX_wm_view3d(pcontext->C),
+ NULL,
+ NULL,
+ NULL);
+ GPU_matrix_push();
+ GPU_matrix_mul(pcontext->vc.obact->obmat);
+
+ /* Draw the special active cursors different tools may have. */
+
+ if (brush->sculpt_tool == SCULPT_TOOL_GRAB) {
+ sculpt_geometry_preview_lines_draw(pcontext->pos, brush, pcontext->is_multires, ss);
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE) {
+ SCULPT_multiplane_scrape_preview_draw(
+ pcontext->pos, brush, ss, pcontext->outline_col, pcontext->outline_alpha);
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
+ if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
+ SCULPT_cloth_plane_falloff_preview_draw(
+ pcontext->pos, ss, pcontext->outline_col, pcontext->outline_alpha);
}
- /* Use special paint crosshair cursor in all paint modes. */
- wmWindow *win = CTX_wm_window(C);
- WM_cursor_set(win, WM_CURSOR_PAINT);
-
- if ((mode == PAINT_MODE_SCULPT) && ss &&
- (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)) {
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-
- if (!ups->stroke_active) {
- bool update_previews = false;
- if (is_cursor_over_mesh && !alpha_overlay_active) {
-
- if (prev_active_vertex_index != ss->active_vertex_index) {
- update_previews = true;
- }
-
- float rds;
- if (!BKE_brush_use_locked_size(scene, brush)) {
- rds = paint_calc_object_space_radius(
- &vc, gi.location, BKE_brush_size_get(scene, brush));
- }
- else {
- rds = BKE_brush_unprojected_radius_get(scene, brush);
- }
-
- wmViewport(&region->winrct);
-
- /* Draw 3D active vertex preview with symmetry. */
- if (len_v3v3(gi.active_vertex_co, gi.location) < rds) {
- cursor_draw_point_with_symmetry(pos, region, gi.active_vertex_co, sd, vc.obact, rds);
- }
-
- /* Draw pose brush origins. */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
-
- /* Just after switching to the Pose Brush, the active vertex can be the same and the
- * cursor won't be tagged to update, so always initialize the preview chain if it is
- * null before drawing it. */
- if (update_previews || !ss->pose_ik_chain_preview) {
- BKE_sculpt_update_object_for_edit(depsgraph, vc.obact, true, false, false);
-
- /* Free the previous pose brush preview. */
- if (ss->pose_ik_chain_preview) {
- SCULPT_pose_ik_chain_free(ss->pose_ik_chain_preview);
- }
-
- /* Generate a new pose brush preview from the current cursor location. */
- ss->pose_ik_chain_preview = SCULPT_pose_ik_chain_init(
- sd, vc.obact, ss, brush, gi.location, rds);
- }
-
- /* Draw the pose brush rotation origins. */
- for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
- cursor_draw_point_screen_space(pos,
- region,
- ss->pose_ik_chain_preview->segments[i].initial_orig,
- vc.obact->obmat,
- 3);
- }
- }
-
- /* Draw 3D brush cursor. */
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
-
- float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
- float quat[4];
-
- copy_m4_m4(cursor_trans, vc.obact->obmat);
- translate_m4(cursor_trans, gi.location[0], gi.location[1], gi.location[2]);
- rotation_between_vecs_to_quat(quat, z_axis, gi.normal);
- quat_to_mat4(cursor_rot, quat);
-
- GPU_matrix_push();
- GPU_matrix_mul(cursor_trans);
- GPU_matrix_mul(cursor_rot);
- immUniformColor3fvAlpha(outline_col, outline_alpha);
- GPU_line_width(2.0f);
- imm_draw_circle_wire_3d(pos, 0, 0, rds, 80);
-
- GPU_line_width(1.0f);
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.5f);
- imm_draw_circle_wire_3d(pos, 0, 0, rds * clamp_f(brush->alpha, 0.0f, 1.0f), 80);
- GPU_matrix_pop();
-
- /* Cloth brush simulation areas. */
- if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
- GPU_matrix_push();
- const float white[3] = {1.0f, 1.0f, 1.0f};
- SCULPT_cloth_simulation_limits_draw(
- pos, brush, vc.obact->obmat, gi.location, gi.normal, rds, 1.0f, white, 0.25f);
- GPU_matrix_pop();
- }
-
- /* Layer brush height. */
- if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
- GPU_matrix_push();
- SCULPT_layer_brush_height_preview_draw(pos,
- brush,
- vc.obact->obmat,
- gi.location,
- gi.normal,
- rds,
- 1.0f,
- outline_col,
- outline_alpha);
- GPU_matrix_pop();
- }
-
- /* Update and draw dynamic mesh preview lines. */
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) &&
- !is_multires) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) {
- SCULPT_geometry_preview_lines_update(C, ss, rds);
- sculpt_geometry_preview_lines_draw(pos, ss);
- }
- }
-
- /* Draw pose brush line preview. */
- if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
- immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
- GPU_line_width(2.0f);
-
- immBegin(GPU_PRIM_LINES, ss->pose_ik_chain_preview->tot_segments * 2);
- for (int i = 0; i < ss->pose_ik_chain_preview->tot_segments; i++) {
- immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_orig);
- immVertex3fv(pos, ss->pose_ik_chain_preview->segments[i].initial_head);
- }
-
- immEnd();
- }
-
- GPU_matrix_pop();
-
- GPU_matrix_pop_projection();
-
- wmWindowViewport(win);
- }
- else {
- /* Draw default cursor when the mouse is not over the mesh or there are no supported
- * overlays active. */
- GPU_line_width(1.0f);
- /* Reduce alpha to increase the contrast when the cursor is over the mesh. */
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.8);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 80);
- immUniformColor3fvAlpha(outline_col, outline_alpha * 0.35f);
- imm_draw_circle_wire_3d(pos,
- translation[0],
- translation[1],
- final_radius * clamp_f(brush->alpha, 0.0f, 1.0f),
- 80);
- }
- }
- else {
- if (vc.obact->sculpt->cache &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(vc.obact->sculpt->cache)) {
- wmViewport(&region->winrct);
-
- /* Draw cached dynamic mesh preview lines. */
- if (brush->sculpt_tool == SCULPT_TOOL_GRAB && (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) &&
- !is_multires) {
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && ss->deform_modifiers_active) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- sculpt_geometry_preview_lines_draw(pos, ss);
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
- }
- }
-
- if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE &&
- brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(wm,
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- SCULPT_multiplane_scrape_preview_draw(pos, ss, outline_col, outline_alpha);
- GPU_matrix_pop();
- GPU_matrix_pop_projection();
- }
-
- if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
- !SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
- GPU_matrix_push_projection();
- ED_view3d_draw_setup_view(CTX_wm_manager(C),
- CTX_wm_window(C),
- CTX_data_depsgraph_pointer(C),
- CTX_data_scene(C),
- region,
- CTX_wm_view3d(C),
- NULL,
- NULL,
- NULL);
-
- /* Plane falloff preview */
- if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) {
- GPU_matrix_push();
- GPU_matrix_mul(vc.obact->obmat);
- SCULPT_cloth_plane_falloff_preview_draw(pos, ss, outline_col, outline_alpha);
- GPU_matrix_pop();
- }
-
- /* Display the simulation limits if sculpting outside them. */
- /* This does not makes much sense of plane fallof as the fallof is infinte. */
- else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL) {
- if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
- ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
- const float red[3] = {1.0f, 0.2f, 0.2f};
- GPU_matrix_push();
- SCULPT_cloth_simulation_limits_draw(pos,
- brush,
- vc.obact->obmat,
- ss->cache->true_initial_location,
- ss->cache->true_initial_normal,
- ss->cache->radius,
- 2.0f,
- red,
- 0.8f);
- GPU_matrix_pop();
- }
- }
-
- GPU_matrix_pop_projection();
- }
-
- wmWindowViewport(win);
- }
+ else if (brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_RADIAL &&
+ brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ /* Display the simulation limits if sculpting outside them. */
+ /* This does not makes much sense of plane fallof as the fallof is infinte or global. */
+
+ if (len_v3v3(ss->cache->true_location, ss->cache->true_initial_location) >
+ ss->cache->radius * (1.0f + brush->cloth_sim_limit)) {
+ const float red[3] = {1.0f, 0.2f, 0.2f};
+ SCULPT_cloth_simulation_limits_draw(pcontext->pos,
+ brush,
+ ss->cache->true_initial_location,
+ ss->cache->true_initial_normal,
+ ss->cache->radius,
+ 2.0f,
+ red,
+ 0.8f);
}
}
- else {
- /* Draw default cursor in unsupported modes. */
- GPU_line_width(1.0f);
- imm_draw_circle_wire_3d(pos, translation[0], translation[1], final_radius, 40);
+ }
+
+ GPU_matrix_pop();
+
+ /* This Cloth brush cursor overlay always works in cursor space. */
+ paint_cursor_drawing_setup_cursor_space(pcontext);
+
+ GPU_matrix_pop_projection();
+ wmWindowViewport(pcontext->win);
+}
+
+static void paint_cursor_draw_3D_view_brush_cursor(PaintCursorContext *pcontext)
+{
+
+ /* These paint tools are not using the SculptSession, so they need to use the default 2D brush
+ * cursor in the 3D view. */
+ if (pcontext->mode != PAINT_MODE_SCULPT || !pcontext->ss) {
+ paint_draw_legacy_3D_view_brush_cursor(pcontext);
+ return;
+ }
+
+ paint_cursor_sculpt_session_update_and_init(pcontext);
+
+ if (pcontext->is_stroke_active) {
+ paint_cursor_cursor_draw_3d_view_brush_cursor_active(pcontext);
+ }
+ else {
+ paint_cursor_draw_3d_view_brush_cursor_inactive(pcontext);
+ }
+}
+
+static bool paint_cursor_is_3d_view_navigating(PaintCursorContext *pcontext)
+{
+ ViewContext *vc = &pcontext->vc;
+ return vc->rv3d && (vc->rv3d->rflag & RV3D_NAVIGATING);
+}
+
+static bool paint_cursor_is_brush_cursor_enabled(PaintCursorContext *pcontext)
+{
+ if (pcontext->paint->flags & PAINT_SHOW_BRUSH) {
+ if (ELEM(pcontext->mode, PAINT_MODE_TEXTURE_2D, PAINT_MODE_TEXTURE_3D) &&
+ pcontext->brush->imagepaint_tool == PAINT_TOOL_FILL) {
+ return false;
}
+ return true;
}
+ return false;
+}
- immUnbindProgram();
+static void paint_cursor_update_rake_rotation(PaintCursorContext *pcontext)
+{
+ /* Don't calculate rake angles while a stroke is active because the rake variables are global
+ * and we may get interference with the stroke itself.
+ * For line strokes, such interference is visible. */
+ if (!pcontext->ups->stroke_active) {
+ paint_calculate_rake_rotation(pcontext->ups, pcontext->brush, pcontext->translation);
+ }
+}
- /* Restore GL state. */
+static void paint_cursor_check_and_draw_alpha_overlays(PaintCursorContext *pcontext)
+{
+ pcontext->alpha_overlay_drawn = paint_draw_alpha_overlay(pcontext->ups,
+ pcontext->brush,
+ &pcontext->vc,
+ pcontext->x,
+ pcontext->y,
+ pcontext->zoomx,
+ pcontext->mode);
+}
+
+static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext)
+{
+ UnifiedPaintSettings *ups = pcontext->ups;
+ if (ups->draw_anchored) {
+ pcontext->final_radius = ups->anchored_size;
+ copy_v2_fl2(pcontext->translation,
+ ups->anchored_initial_mouse[0] + pcontext->region->winrct.xmin,
+ ups->anchored_initial_mouse[1] + pcontext->region->winrct.ymin);
+ }
+}
+
+static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext)
+{
+ GPU_line_width(2.0f);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ pcontext->pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+}
+
+static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext)
+{
+ GPU_line_width(2.0f);
+ GPU_blend(true);
+ GPU_line_smooth(true);
+ pcontext->pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+}
+
+static void paint_cursor_restore_drawing_state(void)
+{
+ immUnbindProgram();
GPU_blend(false);
GPU_line_smooth(false);
}
+static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
+{
+ PaintCursorContext pcontext;
+ if (!paint_cursor_context_init(C, x, y, &pcontext)) {
+ return;
+ }
+
+ if (!paint_cursor_is_brush_cursor_enabled(&pcontext)) {
+ return;
+ }
+ if (paint_cursor_is_3d_view_navigating(&pcontext)) {
+ return;
+ }
+
+ switch (pcontext.cursor_type) {
+ case PAINT_CURSOR_CURVE:
+ paint_draw_curve_cursor(pcontext.brush, &pcontext.vc);
+ break;
+ case PAINT_CURSOR_2D:
+ paint_cursor_update_rake_rotation(&pcontext);
+ paint_cursor_check_and_draw_alpha_overlays(&pcontext);
+ paint_cursor_update_anchored_location(&pcontext);
+
+ paint_cursor_setup_2D_drawing(&pcontext);
+ paint_draw_2D_view_brush_cursor(&pcontext);
+ paint_cursor_restore_drawing_state();
+ break;
+ case PAINT_CURSOR_3D:
+ paint_update_mouse_cursor(&pcontext);
+
+ paint_cursor_update_rake_rotation(&pcontext);
+ paint_cursor_check_and_draw_alpha_overlays(&pcontext);
+ paint_cursor_update_anchored_location(&pcontext);
+
+ paint_cursor_setup_3D_drawing(&pcontext);
+ paint_cursor_draw_3D_view_brush_cursor(&pcontext);
+ paint_cursor_restore_drawing_state();
+ break;
+ }
+}
+
/* Public API */
void paint_cursor_start(Paint *p, bool (*poll)(bContext *C))
diff --git a/source/blender/editors/sculpt_paint/paint_curve.c b/source/blender/editors/sculpt_paint/paint_curve.c
index 74e022bf84f..458f021ddb4 100644
--- a/source/blender/editors/sculpt_paint/paint_curve.c
+++ b/source/blender/editors/sculpt_paint/paint_curve.c
@@ -193,7 +193,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2])
PaintCurvePoint *pcp;
wmWindow *window = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
- float vec[3] = {loc[0], loc[1], 0.0};
+ const float vec[3] = {loc[0], loc[1], 0.0};
int add_index;
int i;
@@ -251,7 +251,7 @@ static void paintcurve_point_add(bContext *C, wmOperator *op, const int loc[2])
static int paintcurve_add_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- int loc[2] = {event->mval[0], event->mval[1]};
+ const int loc[2] = {event->mval[0], event->mval[1]};
paintcurve_point_add(C, op, loc);
RNA_int_set_array(op->ptr, "location", loc);
return OPERATOR_FINISHED;
@@ -480,7 +480,7 @@ static bool paintcurve_point_select(
static int paintcurve_select_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- int loc[2] = {UNPACK2(event->mval)};
+ const int loc[2] = {UNPACK2(event->mval)};
bool toggle = RNA_boolean_get(op->ptr, "toggle");
bool extend = RNA_boolean_get(op->ptr, "extend");
if (paintcurve_point_select(C, op, loc, toggle, extend)) {
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 7ee3d991eb7..431ab998f62 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -74,7 +74,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -182,7 +181,7 @@ void imapaint_image_update(
int h = imapaintpartial.y2 - imapaintpartial.y1;
if (w && h) {
/* Testing with partial update in uv editor too */
- GPU_paint_update_image(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h);
+ BKE_image_update_gputexture(image, iuser, imapaintpartial.x1, imapaintpartial.y1, w, h);
}
}
}
@@ -1164,9 +1163,9 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob
BKE_paint_toolslots_brush_validate(bmain, &imapaint->paint);
if (U.glreslimit != 0) {
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
}
- GPU_paint_set_mipmap(bmain, 0);
+ BKE_image_paint_set_mipmap(bmain, 0);
toggle_paint_cursor(scene, true);
@@ -1189,9 +1188,9 @@ void ED_object_texture_paint_mode_exit_ex(Main *bmain, Scene *scene, Object *ob)
ob->mode &= ~OB_MODE_TEXTURE_PAINT;
if (U.glreslimit != 0) {
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
}
- GPU_paint_set_mipmap(bmain, 1);
+ BKE_image_paint_set_mipmap(bmain, 1);
toggle_paint_cursor(scene, false);
Mesh *me = BKE_mesh_from_object(ob);
@@ -1334,7 +1333,7 @@ void ED_imapaint_bucket_fill(struct bContext *C,
ED_image_undo_push_begin(op->type->name, PAINT_MODE_TEXTURE_2D);
- float mouse_init[2] = {mouse[0], mouse[1]};
+ const float mouse_init[2] = {mouse[0], mouse[1]};
paint_2d_bucket_fill(C, color, NULL, mouse_init, NULL, NULL);
ED_image_undo_push_end();
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index a7f09390a3d..d614c800350 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -57,8 +57,6 @@
#include "UI_view2d.h"
-#include "GPU_draw.h"
-
#include "paint_intern.h"
/* Brush Painting for 2D image editor */
@@ -1784,7 +1782,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final)
if (final) {
if (s->image && !(s->sima && s->sima->lock)) {
- GPU_free_image(s->image);
+ BKE_image_free_gputextures(s->image);
}
/* compositor listener deals with updating */
@@ -2165,7 +2163,7 @@ void paint_2d_gradient_fill(
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
float f;
- float p[2] = {x_px - image_init[0], y_px - image_init[1]};
+ const float p[2] = {x_px - image_init[0], y_px - image_init[1]};
switch (br->gradient_fill_mode) {
case BRUSH_GRADIENT_LINEAR: {
@@ -2193,7 +2191,7 @@ void paint_2d_gradient_fill(
for (x_px = 0; x_px < ibuf->x; x_px++) {
for (y_px = 0; y_px < ibuf->y; y_px++) {
float f;
- float p[2] = {x_px - image_init[0], y_px - image_init[1]};
+ const float p[2] = {x_px - image_init[0], y_px - image_init[1]};
switch (br->gradient_fill_mode) {
case BRUSH_GRADIENT_LINEAR: {
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 5af3a3f4241..d16c66848b8 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -100,8 +100,6 @@
#include "RNA_define.h"
#include "RNA_enum_types.h"
-#include "GPU_draw.h"
-
#include "IMB_colormanagement.h"
//#include "bmesh_tools.h"
@@ -2930,7 +2928,7 @@ static void project_bucket_clip_face(const bool is_ortho,
/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
* otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
-static bool IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
+static bool IsectPoly2Df(const float pt[2], const float uv[][2], const int tot)
{
int i;
if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f) {
@@ -2945,7 +2943,7 @@ static bool IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
return true;
}
-static bool IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
+static bool IsectPoly2Df_twoside(const float pt[2], const float uv[][2], const int tot)
{
const bool side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f);
@@ -3311,7 +3309,7 @@ static void project_paint_face_init(const ProjPaintState *ps,
has_x_isect = 0;
for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
- float puv[2] = {(float)x, (float)y};
+ const float puv[2] = {(float)x, (float)y};
bool in_bounds;
// uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
/* use offset uvs instead */
@@ -5758,7 +5756,7 @@ void paint_proj_stroke(const bContext *C,
View3D *v3d = CTX_wm_view3d(C);
ARegion *region = CTX_wm_region(C);
float *cursor = scene->cursor.location;
- int mval_i[2] = {(int)pos[0], (int)pos[1]};
+ const int mval_i[2] = {(int)pos[0], (int)pos[1]};
view3d_operator_needs_opengl(C);
@@ -6125,8 +6123,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- float pos[2] = {0.0, 0.0};
- float lastpos[2] = {0.0, 0.0};
+ const float pos[2] = {0.0, 0.0};
+ const float lastpos[2] = {0.0, 0.0};
int a;
project_paint_op(&ps, lastpos, pos);
@@ -6134,7 +6132,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
project_image_refresh_tagged(&ps);
for (a = 0; a < ps.image_tot; a++) {
- GPU_free_image(ps.projImages[a].ima);
+ BKE_image_free_gputextures(ps.projImages[a].ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
}
@@ -6175,7 +6173,7 @@ static bool texture_paint_image_from_view_poll(bContext *C)
CTX_wm_operator_poll_msg_set(C, "No 3D viewport found to create image from");
return false;
}
- if (G.background || !GPU_is_initialized()) {
+ if (G.background || !GPU_is_init()) {
return false;
}
return true;
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index d532ef977fe..65f78a2d988 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -340,6 +340,7 @@ typedef enum {
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot);
void PAINT_OT_mask_lasso_gesture(struct wmOperatorType *ot);
+void PAINT_OT_mask_box_gesture(struct wmOperatorType *ot);
/* paint_curve.c */
void PAINTCURVE_OT_new(struct wmOperatorType *ot);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 6e0402fc6e0..7e5825835fb 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -25,6 +25,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "DNA_vec_types.h"
#include "BLI_bitmap_draw_2d.h"
#include "BLI_lasso_2d.h"
@@ -290,27 +291,32 @@ static void mask_box_select_task_cb(void *__restrict userdata,
}
}
-bool ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select)
+static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
{
+ ViewContext vc;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- Sculpt *sd = vc->scene->toolsettings->sculpt;
+ ED_view3d_viewcontext_init(C, &vc, depsgraph);
+
+ Sculpt *sd = vc.scene->toolsettings->sculpt;
BoundBox bb;
float clip_planes[4][4];
float clip_planes_final[4][4];
- ARegion *region = vc->region;
- Object *ob = vc->obact;
- PaintMaskFloodMode mode;
+ ARegion *region = vc.region;
+ Object *ob = vc.obact;
bool multires;
PBVH *pbvh;
PBVHNode **nodes;
int totnode;
int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
- mode = PAINT_MASK_FLOOD_VALUE;
- float value = select ? 1.0f : 0.0f;
+ const PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode");
+ const float value = RNA_float_get(op->ptr, "value");
+
+ rcti rect;
+ WM_operator_properties_border_to_rcti(op, &rect);
/* Transform the clip planes in object space. */
- ED_view3d_clipping_calc(&bb, clip_planes, vc->region, vc->obact, rect);
+ ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &rect);
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
pbvh = ob->sculpt->pbvh;
@@ -383,7 +389,7 @@ typedef struct LassoMaskData {
* Lasso select. This could be defined as part of #VIEW3D_OT_select_lasso,
* still the shortcuts conflict, so we will use a separate operator.
*/
-static bool is_effected_lasso(LassoMaskData *data, float co[3])
+static bool is_effected_lasso(LassoMaskData *data, const float co[3])
{
float scr_co_f[2];
int scr_co_s[2];
@@ -589,3 +595,33 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
0.0f,
1.0f);
}
+
+void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
+{
+ ot->name = "Mask Box Gesture";
+ ot->idname = "PAINT_OT_mask_box_gesture";
+ ot->description = "Add mask within the box as you move the brush";
+
+ ot->invoke = WM_gesture_box_invoke;
+ ot->modal = WM_gesture_box_modal;
+ ot->exec = paint_mask_gesture_box_exec;
+
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+
+ /* Properties. */
+ WM_operator_properties_border(ot);
+
+ RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
+ RNA_def_float(
+ ot->srna,
+ "value",
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ "Value",
+ "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
+ 0.0f,
+ 1.0f);
+}
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index d65f158174f..43ff03ea7e2 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -913,7 +913,7 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev
{
Paint *paint = BKE_paint_get_active_from_context(C);
Brush *br = BKE_paint_brush(paint);
- float mvalf[2] = {event->mval[0], event->mval[1]};
+ const float mvalf[2] = {event->mval[0], event->mval[1]};
ARegion *region = CTX_wm_region(C);
StencilControlData *scd;
int mask = RNA_enum_get(op->ptr, "texmode");
@@ -968,7 +968,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2]
#define PIXEL_MARGIN 5
float mdiff[2];
- float mvalf[2] = {mval[0], mval[1]};
+ const float mvalf[2] = {mval[0], mval[1]};
switch (scd->mode) {
case STENCIL_TRANSLATE:
sub_v2_v2v2(mdiff, mvalf, scd->init_mouse);
@@ -1356,6 +1356,7 @@ void ED_operatortypes_paint(void)
/* paint masking */
WM_operatortype_append(PAINT_OT_mask_flood_fill);
WM_operatortype_append(PAINT_OT_mask_lasso_gesture);
+ WM_operatortype_append(PAINT_OT_mask_box_gesture);
}
void ED_keymap_paint(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index caecc7b708a..38a09cd97bd 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -920,9 +920,9 @@ PaintStroke *paint_stroke_new(bContext *C,
ups->average_stroke_counter = 0;
/* initialize here to avoid initialization conflict with threaded strokes */
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
if (p->flags & PAINT_USE_CAVITY_MASK) {
- BKE_curvemapping_initialize(p->cavity_curve);
+ BKE_curvemapping_init(p->cavity_curve);
}
BKE_paint_set_overlay_override(br->overlay_flags);
@@ -1198,7 +1198,10 @@ static void paint_line_strokes_spacing(bContext *C,
*length_residue = length;
}
-static void paint_stroke_line_end(bContext *C, wmOperator *op, PaintStroke *stroke, float mouse[2])
+static void paint_stroke_line_end(bContext *C,
+ wmOperator *op,
+ PaintStroke *stroke,
+ const float mouse[2])
{
Brush *br = stroke->brush;
if (stroke->stroke_started && (br->flag & BRUSH_LINE)) {
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 6c5d6f4ee4e..b7e5a73cbb3 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -169,7 +169,7 @@ float paint_get_tex_pixel(const MTex *mtex, float u, float v, struct ImagePool *
{
float intensity;
float rgba_dummy[4];
- float co[3] = {u, v, 0.0f};
+ const float co[3] = {u, v, 0.0f};
RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba_dummy);
@@ -185,7 +185,7 @@ void paint_get_tex_pixel_col(const MTex *mtex,
bool convert_to_linear,
struct ColorSpace *colorspace)
{
- float co[3] = {u, v, 0.0f};
+ const float co[3] = {u, v, 0.0f};
float intensity;
const bool hasrgb = RE_texture_evaluate(mtex, co, thread, pool, false, false, &intensity, rgba);
@@ -238,7 +238,7 @@ void paint_stroke_operator_properties(wmOperatorType *ot)
/* 3D Paint */
-static void imapaint_project(float matrix[4][4], const float co[3], float pco[4])
+static void imapaint_project(const float matrix[4][4], const float co[3], float pco[4])
{
copy_v3_v3(pco, co);
pco[3] = 1.0f;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index 6965946d2ce..73014f9f2de 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -757,8 +757,8 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
int y_start = RNA_int_get(op->ptr, "ystart");
int x_end = RNA_int_get(op->ptr, "xend");
int y_end = RNA_int_get(op->ptr, "yend");
- float sco_start[2] = {x_start, y_start};
- float sco_end[2] = {x_end, y_end};
+ const float sco_start[2] = {x_start, y_start};
+ const float sco_end[2] = {x_end, y_end};
const bool is_interactive = (gesture != NULL);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
@@ -811,7 +811,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
VPaint *wp = ts->wpaint;
struct Brush *brush = BKE_paint_brush(&wp->paint);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
data.brush = brush;
data.weightpaint = BKE_brush_weight_get(scene, brush);
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index e838d87aeff..d0b834a3dc0 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -196,7 +196,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
}
}
-static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index)
+const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
{
if (ss->persistent_base) {
return ss->persistent_base[index].co;
@@ -204,7 +204,7 @@ static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index
return SCULPT_vertex_co_get(ss, index);
}
-static void sculpt_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
+void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
{
if (ss->persistent_base) {
copy_v3_v3(no, ss->persistent_base[index].no);
@@ -581,7 +581,8 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss
p1 = vert_map->indices[i];
break;
}
- else if (p2 == -1) {
+
+ if (p2 == -1) {
p2 = vert_map->indices[i];
break;
}
@@ -2966,7 +2967,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
/* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
@@ -3043,7 +3044,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
/* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
* initialize before threads so they can do curve mapping. */
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
@@ -3273,7 +3274,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
return;
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
SculptThreadedTaskData data = {
.sd = sd,
@@ -4341,9 +4342,9 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata,
float normal[3];
if (use_persistent_base) {
- sculpt_vertex_persistent_normal_get(ss, vi, normal);
+ SCULPT_vertex_persistent_normal_get(ss, vi, normal);
mul_v3_fl(normal, brush->height);
- madd_v3_v3v3fl(final_co, sculpt_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
+ madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
}
else {
normal_short_to_float_v3(normal, orig_data.no);
@@ -5513,15 +5514,21 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
}
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
- SculptSearchSphereData data = {
- .ss = ss,
- .sd = sd,
- .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
- .original = false,
- .ignore_fully_ineffective = false,
- .center = ss->cache->initial_location,
- };
- BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
+ if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
+ SculptSearchSphereData data = {
+ .ss = ss,
+ .sd = sd,
+ .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
+ .original = false,
+ .ignore_fully_ineffective = false,
+ .center = ss->cache->initial_location,
+ };
+ BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
+ }
+ else {
+ /* Gobal simulation, get all nodes. */
+ BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+ }
}
else {
const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
@@ -6390,7 +6397,7 @@ static void sculpt_update_cache_invariants(
brush = br;
cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
BKE_brush_size_set(scene, brush, size);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
}
}
}
@@ -6458,7 +6465,7 @@ static void sculpt_update_cache_invariants(
#define PIXEL_INPUT_THRESHHOLD 5
if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
- cache->dial = BLI_dial_initialize(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
+ cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
}
#undef PIXEL_INPUT_THRESHHOLD
@@ -8160,6 +8167,14 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
return;
}
+ if (!ss->deform_modifiers_active) {
+ return;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
+ return;
+ }
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
if (!ss->pmap) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c
index 4232be91034..21fba6479e8 100644
--- a/source/blender/editors/sculpt_paint/sculpt_cloth.c
+++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c
@@ -43,7 +43,9 @@
#include "DNA_scene_types.h"
#include "BKE_brush.h"
+#include "BKE_bvhutils.h"
#include "BKE_ccg.h"
+#include "BKE_collision.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_image.h"
@@ -69,6 +71,7 @@
#include "BKE_subsurf.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "WM_api.h"
#include "WM_message.h"
@@ -85,7 +88,6 @@
#include "RNA_access.h"
#include "RNA_define.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -101,6 +103,33 @@
#include <stdlib.h>
#include <string.h>
+static float cloth_brush_simulation_falloff_get(const Brush *brush,
+ const float radius,
+ const float location[3],
+ const float co[3])
+{
+ /* Global simulation does not have any falloff as the entire mesh is being simulated. */
+ if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_GLOBAL) {
+ return 1.0f;
+ }
+
+ const float distance = len_v3v3(location, co);
+ const float limit = radius + (radius * brush->cloth_sim_limit);
+ const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
+
+ if (distance > limit) {
+ /* Outiside the limits. */
+ return 0.0f;
+ }
+ if (distance < falloff) {
+ /* Before the falloff area. */
+ return 1.0f;
+ }
+ /* Do a smoothstep transition inside the falloff area. */
+ float p = 1.0f - ((distance - falloff) / (limit - falloff));
+ return 3.0f * p * p - 2.0f * p * p * p;
+}
+
#define CLOTH_LENGTH_CONSTRAINTS_BLOCK 100000
#define CLOTH_SIMULATION_ITERATIONS 5
#define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024
@@ -113,19 +142,8 @@ static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_s
return BLI_edgeset_haskey(cloth_sim->created_length_constraints, v1, v2);
}
-static void cloth_brush_add_length_constraint(SculptSession *ss,
- SculptClothSimulation *cloth_sim,
- const int v1,
- const int v2)
+static void cloth_brush_reallocate_constraints(SculptClothSimulation *cloth_sim)
{
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v1 = v1;
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].v2 = v2;
- cloth_sim->length_constraints[cloth_sim->tot_length_constraints].length = len_v3v3(
- SCULPT_vertex_co_get(ss, v1), SCULPT_vertex_co_get(ss, v2));
-
- cloth_sim->tot_length_constraints++;
-
- /* Reallocation if the array capacity is exceeded. */
if (cloth_sim->tot_length_constraints >= cloth_sim->capacity_length_constraints) {
cloth_sim->capacity_length_constraints += CLOTH_LENGTH_CONSTRAINTS_BLOCK;
cloth_sim->length_constraints = MEM_reallocN_id(cloth_sim->length_constraints,
@@ -133,23 +151,119 @@ static void cloth_brush_add_length_constraint(SculptSession *ss,
sizeof(SculptClothLengthConstraint),
"length constraints");
}
+}
+
+static void cloth_brush_add_length_constraint(SculptSession *ss,
+ SculptClothSimulation *cloth_sim,
+ const int v1,
+ const int v2,
+ const bool use_persistent)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v1;
+ length_constraint->elem_index_b = v2;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v1];
+ length_constraint->elem_position_b = cloth_sim->pos[v2];
+
+ if (use_persistent) {
+ length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1),
+ SCULPT_vertex_persistent_co_get(ss, v2));
+ }
+ else {
+ length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, v1),
+ SCULPT_vertex_co_get(ss, v2));
+ }
+ length_constraint->strength = 1.0f;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
/* Add the constraint to the GSet to avoid creating it again. */
BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2);
}
+static void cloth_brush_add_softbody_constraint(SculptClothSimulation *cloth_sim,
+ const int v,
+ const float strength)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v;
+ length_constraint->elem_index_b = v;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v];
+ length_constraint->elem_position_b = cloth_sim->init_pos[v];
+
+ length_constraint->length = 0.0f;
+ length_constraint->strength = strength;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
+}
+
+static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_sim,
+ const int v,
+ const float strength)
+{
+ SculptClothLengthConstraint *length_constraint =
+ &cloth_sim->length_constraints[cloth_sim->tot_length_constraints];
+
+ length_constraint->elem_index_a = v;
+ length_constraint->elem_index_b = v;
+
+ length_constraint->elem_position_a = cloth_sim->pos[v];
+ length_constraint->elem_position_b = cloth_sim->deformation_pos[v];
+
+ length_constraint->length = 0.0f;
+ length_constraint->strength = strength;
+
+ cloth_sim->tot_length_constraints++;
+
+ /* Reallocation if the array capacity is exceeded. */
+ cloth_brush_reallocate_constraints(cloth_sim);
+}
+
static void do_cloth_brush_build_constraints_task_cb_ex(
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
PBVHVertexIter vd;
+ const bool pin_simulation_boundary = ss->cache != NULL && brush != NULL &&
+ brush->flag2 & BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY;
+
+ const bool use_persistent = brush != NULL && brush->flag & BRUSH_PERSISTENT;
+
+ /* Brush can be NULL in tools that use the solver without relying of constraints with deformation
+ * positions. */
+ const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL &&
+ SCULPT_is_cloth_deform_brush(brush);
+ float radius_squared = 0.0f;
+ if (cloth_is_deform_brush) {
+ radius_squared = ss->cache->initial_radius * ss->cache->initial_radius;
+ }
+
+ /* Only limit the contraint creation to a radius when the simulation is local. */
+ const float cloth_sim_radius_squared = brush->cloth_simulation_area_type ==
+ BRUSH_CLOTH_SIMULATION_AREA_LOCAL ?
+ data->cloth_sim_radius * data->cloth_sim_radius :
+ FLT_MAX;
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (len_squared_v3v3(vd.co, data->cloth_sim_initial_location) <
- data->cloth_sim_radius * data->cloth_sim_radius) {
+ const float len_squared = len_squared_v3v3(vd.co, data->cloth_sim_initial_location);
+ if (len_squared < cloth_sim_radius_squared) {
SculptVertexNeighborIter ni;
int build_indices[CLOTH_MAX_CONSTRAINTS_PER_VERTEX];
@@ -162,6 +276,11 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
}
SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+ if (brush->cloth_constraint_softbody_strength > 0.0f) {
+ cloth_brush_add_softbody_constraint(
+ data->cloth_sim, vd.index, brush->cloth_constraint_softbody_strength);
+ }
+
/* As we don't know the order of the neighbor vertices, we create all possible combinations
* between the neighbor and the original vertex as length constraints. */
/* This results on a pattern that contains structural, shear and bending constraints for all
@@ -172,35 +291,29 @@ static void do_cloth_brush_build_constraints_task_cb_ex(
if (c_i != c_j && !cloth_brush_sim_has_length_constraint(
data->cloth_sim, build_indices[c_i], build_indices[c_j])) {
cloth_brush_add_length_constraint(
- ss, data->cloth_sim, build_indices[c_i], build_indices[c_j]);
+ ss, data->cloth_sim, build_indices[c_i], build_indices[c_j], use_persistent);
}
}
}
}
- }
- BKE_pbvh_vertex_iter_end;
-}
-static float cloth_brush_simulation_falloff_get(const Brush *brush,
- const float radius,
- const float location[3],
- const float co[3])
-{
- const float distance = len_v3v3(location, co);
- const float limit = radius + (radius * brush->cloth_sim_limit);
- const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff);
+ if (cloth_is_deform_brush && len_squared < radius_squared) {
+ const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius);
+ cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade);
+ }
- if (distance > limit) {
- /* Outiside the limits. */
- return 0.0f;
- }
- if (distance < falloff) {
- /* Before the falloff area. */
- return 1.0f;
+ if (pin_simulation_boundary) {
+ const float sim_falloff = cloth_brush_simulation_falloff_get(
+ brush, ss->cache->initial_radius, ss->cache->location, vd.co);
+ /* Vertex is inside the area of the simulation without any falloff aplied. */
+ if (sim_falloff < 1.0f) {
+ /* Create constraints with more strength the closer the vertex is to the simulation
+ * boundary. */
+ cloth_brush_add_softbody_constraint(data->cloth_sim, vd.index, 1.0f - sim_falloff);
+ }
+ }
}
- /* Do a smoothstep transition inside the falloff area. */
- float p = 1.0f - ((distance - falloff) / (limit - falloff));
- return 3.0f * p * p - 2.0f * p * p * p;
+ BKE_pbvh_vertex_iter_end;
}
static void cloth_brush_apply_force_to_vertex(SculptSession *UNUSED(ss),
@@ -323,9 +436,10 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
mul_v3_v3fl(force, offset, -fade);
break;
case BRUSH_CLOTH_DEFORM_GRAB:
- /* Grab writes the positions in the simulation directly without applying forces. */
- madd_v3_v3v3fl(
- cloth_sim->pos[vd.index], orig_data.co, ss->cache->grab_delta_symmetry, fade);
+ madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index],
+ orig_data.co,
+ ss->cache->grab_delta_symmetry,
+ fade);
zero_v3(force);
break;
case BRUSH_CLOTH_DEFORM_PINCH_POINT:
@@ -366,9 +480,36 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
}
+static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph)
+{
+ ListBase *cache = NULL;
+ DEG_OBJECT_ITER_BEGIN (depsgraph,
+ ob,
+ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_VISIBLE |
+ DEG_ITER_OBJECT_FLAG_DUPLI) {
+ CollisionModifierData *cmd = (CollisionModifierData *)BKE_modifiers_findby_type(
+ ob, eModifierType_Collision);
+ if (cmd && cmd->bvhtree) {
+ if (cache == NULL) {
+ cache = MEM_callocN(sizeof(ListBase), "ColliderCache array");
+ }
+
+ ColliderCache *col = MEM_callocN(sizeof(ColliderCache), "ColliderCache");
+ col->ob = ob;
+ col->collmd = cmd;
+ collision_move_object(cmd, 1.0, 0.0, true);
+ BLI_addtail(cache, col);
+ }
+ }
+ DEG_OBJECT_ITER_END;
+ return cache;
+}
+
static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss,
+ Brush *brush,
const float cloth_mass,
- const float cloth_damping)
+ const float cloth_damping,
+ const bool use_collisions)
{
const int totverts = SCULPT_vertex_count_get(ss);
SculptClothSimulation *cloth_sim;
@@ -380,19 +521,130 @@ static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss,
"cloth length constraints");
cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK;
- cloth_sim->acceleration = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim acceleration");
- cloth_sim->pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim pos");
- cloth_sim->prev_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim prev pos");
- cloth_sim->init_pos = MEM_callocN(sizeof(float) * 3 * totverts, "cloth sim init pos");
- cloth_sim->length_constraint_tweak = MEM_callocN(sizeof(float) * totverts,
- "cloth sim length tweak");
+ cloth_sim->acceleration = MEM_calloc_arrayN(
+ totverts, 3 * sizeof(float), "cloth sim acceleration");
+ cloth_sim->pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim pos");
+ cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim prev pos");
+ cloth_sim->last_iteration_pos = MEM_calloc_arrayN(
+ totverts, sizeof(float) * 3, "cloth sim last iteration pos");
+ cloth_sim->init_pos = MEM_calloc_arrayN(totverts, 3 * sizeof(float), "cloth sim init pos");
+ cloth_sim->length_constraint_tweak = MEM_calloc_arrayN(
+ totverts, sizeof(float), "cloth sim length tweak");
+
+ /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation
+ * positions. */
+ if (brush && SCULPT_is_cloth_deform_brush(brush)) {
+ cloth_sim->deformation_pos = MEM_calloc_arrayN(
+ totverts, 3 * sizeof(float), "cloth sim deformation positions");
+ }
cloth_sim->mass = cloth_mass;
cloth_sim->damping = cloth_damping;
+ if (use_collisions) {
+ cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph);
+ }
+
return cloth_sim;
}
+typedef struct ClothBrushCollision {
+ CollisionModifierData *col_data;
+ struct IsectRayPrecalc isect_precalc;
+} ClothBrushCollision;
+
+static void cloth_brush_collision_cb(void *userdata,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
+{
+ ClothBrushCollision *col = (ClothBrushCollision *)userdata;
+ CollisionModifierData *col_data = col->col_data;
+ MVertTri *verttri = &col_data->tri[index];
+ MVert *mverts = col_data->x;
+ float *tri[3], no[3], co[3];
+
+ tri[0] = mverts[verttri->tri[0]].co;
+ tri[1] = mverts[verttri->tri[1]].co;
+ tri[2] = mverts[verttri->tri[2]].co;
+ float dist = 0.0f;
+
+ bool tri_hit = isect_ray_tri_watertight_v3(
+ ray->origin, &col->isect_precalc, UNPACK3(tri), &dist, NULL);
+ normal_tri_v3(no, UNPACK3(tri));
+ madd_v3_v3v3fl(co, ray->origin, ray->direction, dist);
+
+ if (tri_hit && dist < hit->dist) {
+ hit->index = index;
+ hit->dist = dist;
+
+ copy_v3_v3(hit->co, co);
+ copy_v3_v3(hit->no, no);
+ }
+}
+
+static void cloth_brush_solve_collision(Object *object,
+ SculptClothSimulation *cloth_sim,
+ const int i)
+{
+ const int raycast_flag = BVH_RAYCAST_DEFAULT & ~(BVH_RAYCAST_WATERTIGHT);
+
+ ColliderCache *collider_cache;
+ BVHTreeRayHit hit;
+
+ float obmat_inv[4][4];
+ invert_m4_m4(obmat_inv, object->obmat);
+
+ for (collider_cache = cloth_sim->collider_list->first; collider_cache;
+ collider_cache = collider_cache->next) {
+ float ray_start[3], ray_normal[3];
+ float pos_world_space[3], prev_pos_world_space[3];
+
+ mul_v3_m4v3(pos_world_space, object->obmat, cloth_sim->pos[i]);
+ mul_v3_m4v3(prev_pos_world_space, object->obmat, cloth_sim->last_iteration_pos[i]);
+ sub_v3_v3v3(ray_normal, pos_world_space, prev_pos_world_space);
+ copy_v3_v3(ray_start, prev_pos_world_space);
+ hit.index = -1;
+ hit.dist = len_v3(ray_normal);
+ normalize_v3(ray_normal);
+
+ ClothBrushCollision col;
+ CollisionModifierData *collmd = collider_cache->collmd;
+ col.col_data = collmd;
+ isect_ray_tri_watertight_v3_precalc(&col.isect_precalc, ray_normal);
+
+ BLI_bvhtree_ray_cast_ex(collmd->bvhtree,
+ ray_start,
+ ray_normal,
+ 0.3f,
+ &hit,
+ cloth_brush_collision_cb,
+ &col,
+ raycast_flag);
+
+ if (hit.index != -1) {
+
+ float collision_disp[3];
+ float movement_disp[3];
+ mul_v3_v3fl(collision_disp, hit.no, 0.005f);
+ sub_v3_v3v3(movement_disp, pos_world_space, prev_pos_world_space);
+ float friction_plane[4];
+ float pos_on_friction_plane[3];
+ plane_from_point_normal_v3(friction_plane, hit.co, hit.no);
+ closest_to_plane_v3(pos_on_friction_plane, friction_plane, pos_world_space);
+ sub_v3_v3v3(movement_disp, pos_on_friction_plane, hit.co);
+
+ /* TODO(pablodp606): This can be exposed in a brush/filter property as friction. */
+ mul_v3_fl(movement_disp, 0.35f);
+
+ copy_v3_v3(cloth_sim->pos[i], hit.co);
+ add_v3_v3(cloth_sim->pos[i], movement_disp);
+ add_v3_v3(cloth_sim->pos[i], collision_disp);
+ mul_v3_m4v3(cloth_sim->pos[i], obmat_inv, cloth_sim->pos[i]);
+ }
+ }
+}
+
static void do_cloth_brush_solve_simulation_task_cb_ex(
void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
{
@@ -423,14 +675,22 @@ static void do_cloth_brush_solve_simulation_task_cb_ex(
const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) *
SCULPT_automasking_factor_get(ss, vd.index);
+
madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v);
madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v);
- copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ if (cloth_sim->collider_list != NULL) {
+ cloth_brush_solve_collision(data->ob, cloth_sim, i);
+ }
+
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
+ copy_v3_v3(cloth_sim->prev_pos[i], temp);
+ copy_v3_v3(cloth_sim->last_iteration_pos[i], cloth_sim->pos[i]);
copy_v3_fl(cloth_sim->acceleration[i], 0.0f);
copy_v3_v3(vd.co, cloth_sim->pos[vd.index]);
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -484,11 +744,11 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
for (int i = 0; i < cloth_sim->tot_length_constraints; i++) {
const SculptClothLengthConstraint *constraint = &cloth_sim->length_constraints[i];
- const int v1 = constraint->v1;
- const int v2 = constraint->v2;
+ const int v1 = constraint->elem_index_a;
+ const int v2 = constraint->elem_index_b;
float v1_to_v2[3];
- sub_v3_v3v3(v1_to_v2, cloth_sim->pos[v2], cloth_sim->pos[v1]);
+ sub_v3_v3v3(v1_to_v2, constraint->elem_position_b, constraint->elem_position_a);
const float current_distance = len_v3(v1_to_v2);
float correction_vector[3];
float correction_vector_half[3];
@@ -524,8 +784,14 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss,
cloth_sim->init_pos[v2]) :
1.0f;
- madd_v3_v3fl(cloth_sim->pos[v1], correction_vector_half, 1.0f * mask_v1 * sim_factor_v1);
- madd_v3_v3fl(cloth_sim->pos[v2], correction_vector_half, -1.0f * mask_v2 * sim_factor_v2);
+ madd_v3_v3fl(cloth_sim->pos[v1],
+ correction_vector_half,
+ 1.0f * mask_v1 * sim_factor_v1 * constraint->strength);
+ if (v1 != v2) {
+ madd_v3_v3fl(cloth_sim->pos[v2],
+ correction_vector_half,
+ -1.0f * mask_v2 * sim_factor_v2 * constraint->strength);
+ }
}
}
}
@@ -577,7 +843,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod
.mat = imat,
};
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Init the grab delta. */
copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
@@ -648,11 +914,20 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
/* The simulation structure only needs to be created on the first symmetry pass. */
if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) {
+ const bool is_cloth_deform_brush = SCULPT_is_cloth_deform_brush(brush);
ss->cache->cloth_sim = cloth_brush_simulation_create(
- ss, brush->cloth_mass, brush->cloth_damping);
+ ss,
+ brush,
+ brush->cloth_mass,
+ brush->cloth_damping,
+ (brush->flag2 & BRUSH_CLOTH_USE_COLLISION));
for (int i = 0; i < totverts; i++) {
- copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(ss->cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
+ copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
+ if (is_cloth_deform_brush) {
+ copy_v3_v3(ss->cache->cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i));
+ }
}
}
@@ -680,18 +955,22 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim)
{
MEM_SAFE_FREE(cloth_sim->pos);
+ MEM_SAFE_FREE(cloth_sim->last_iteration_pos);
MEM_SAFE_FREE(cloth_sim->prev_pos);
MEM_SAFE_FREE(cloth_sim->acceleration);
MEM_SAFE_FREE(cloth_sim->length_constraints);
MEM_SAFE_FREE(cloth_sim->length_constraint_tweak);
+ MEM_SAFE_FREE(cloth_sim->deformation_pos);
MEM_SAFE_FREE(cloth_sim->init_pos);
+ if (cloth_sim->collider_list) {
+ BKE_collider_cache_free(&cloth_sim->collider_list);
+ }
MEM_SAFE_FREE(cloth_sim);
}
/* Cursor drawing function. */
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const Brush *brush,
- const float obmat[4][4],
const float location[3],
const float normal[3],
const float rds,
@@ -700,12 +979,13 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const float alpha)
{
float cursor_trans[4][4], cursor_rot[4][4];
- float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
+ const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f};
float quat[4];
- copy_m4_m4(cursor_trans, obmat);
+ unit_m4(cursor_trans);
translate_m4(cursor_trans, location[0], location[1], location[2]);
rotation_between_vecs_to_quat(quat, z_axis, normal);
quat_to_mat4(cursor_rot, quat);
+ GPU_matrix_push();
GPU_matrix_mul(cursor_trans);
GPU_matrix_mul(cursor_rot);
@@ -715,6 +995,7 @@ void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
gpuattr, 0, 0, rds + (rds * brush->cloth_sim_limit * brush->cloth_sim_falloff), 320);
immUniformColor3fvAlpha(outline_col, alpha * 0.7f);
imm_draw_circle_wire_3d(gpuattr, 0, 0, rds + rds * brush->cloth_sim_limit, 80);
+ GPU_matrix_pop();
}
void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr,
@@ -861,6 +1142,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
const int totverts = SCULPT_vertex_count_get(ss);
+
for (int i = 0; i < totverts; i++) {
copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i));
}
@@ -892,7 +1174,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent
static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
- Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
SculptSession *ss = ob->sculpt;
@@ -913,11 +1195,15 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent
const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass");
const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping");
- ss->filter_cache->cloth_sim = cloth_brush_simulation_create(ss, cloth_mass, cloth_damping);
+ const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions");
+ ss->filter_cache->cloth_sim = cloth_brush_simulation_create(
+ ss, NULL, cloth_mass, cloth_damping, use_collisions);
+
copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss));
const int totverts = SCULPT_vertex_count_get(ss);
for (int i = 0; i < totverts; i++) {
+ copy_v3_v3(ss->filter_cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->filter_cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i));
copy_v3_v3(ss->filter_cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i));
}
@@ -989,4 +1275,9 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot)
false,
"Use Face Sets",
"Apply the filter only to the Face Set under the cursor");
+ ot->prop = RNA_def_boolean(ot->srna,
+ "use_collisions",
+ false,
+ "Use Collisions",
+ "Collide with other collider objects in the scene");
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c
index 463233fd6fb..e08f477c981 100644
--- a/source/blender/editors/sculpt_paint/sculpt_detail.c
+++ b/source/blender/editors/sculpt_paint/sculpt_detail.c
@@ -179,7 +179,7 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my)
SCULPT_vertex_random_access_init(ss);
/* Update the active vertex. */
- float mouse[2] = {mx, my};
+ const float mouse[2] = {mx, my};
SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
@@ -219,7 +219,7 @@ static void sample_detail_dyntopo(bContext *C, ViewContext *vc, ARegion *region,
SCULPT_stroke_modifiers_check(C, ob, brush);
- float mouse[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
+ const float mouse[2] = {mx - region->winrct.xmin, my - region->winrct.ymin};
float ray_start[3], ray_end[3], ray_normal[3];
float depth = SCULPT_raycast_init(vc, mouse, ray_start, ray_end, ray_normal, false);
@@ -316,7 +316,7 @@ static int sculpt_sample_detail_size_modal(bContext *C, wmOperator *op, const wm
switch (event->type) {
case LEFTMOUSE:
if (event->val == KM_PRESS) {
- int ss_co[2] = {event->x, event->y};
+ const int ss_co[2] = {event->x, event->y};
int mode = RNA_enum_get(op->ptr, "mode");
sample_detail(C, ss_co[0], ss_co[1], mode);
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index 1940b007cb0..5cc32be331e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -192,7 +192,7 @@ void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
SculptSession *ss = ob->sculpt;
Brush *brush = BKE_paint_brush(&sd->paint);
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
/* Threaded loop over nodes. */
SculptThreadedTaskData data = {
diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
index e9a98a17f8a..e39cdc2db23 100644
--- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
+++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c
@@ -82,7 +82,7 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type)
ss->filter_cache->random_seed = rand();
- float center[3] = {0.0f};
+ const float center[3] = {0.0f};
SculptSearchSphereData search_data = {
.original = true,
.center = center,
@@ -132,6 +132,7 @@ void SCULPT_filter_cache_free(SculptSession *ss)
MEM_SAFE_FREE(ss->filter_cache->automask);
MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp);
MEM_SAFE_FREE(ss->filter_cache->sharpen_factor);
+ MEM_SAFE_FREE(ss->filter_cache->sharpen_detail_directions);
MEM_SAFE_FREE(ss->filter_cache);
}
@@ -356,6 +357,17 @@ static void mesh_filter_task_cb(void *__restrict userdata,
mul_v3_v3fl(
disp_avg, disp_avg, smooth_ratio * pow2f(ss->filter_cache->sharpen_factor[vd.index]));
add_v3_v3v3(disp, disp_avg, disp_sharpen);
+
+ /* Intensify details. */
+ if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) {
+ float detail_strength[3];
+ normal_short_to_float_v3(detail_strength, orig_data.no);
+ copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]);
+ madd_v3_v3fl(disp,
+ detail_strength,
+ -ss->filter_cache->sharpen_intensify_detail_strength *
+ ss->filter_cache->sharpen_factor[vd.index]);
+ }
break;
}
}
@@ -388,8 +400,10 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
for (int i = 0; i < totvert; i++) {
float avg[3];
SCULPT_neighbor_coords_average(ss, avg, i);
- ss->filter_cache->sharpen_factor[i] = len_v3v3(avg, SCULPT_vertex_co_get(ss, i));
+ sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i));
+ ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]);
}
+
float max_factor = 0.0f;
for (int i = 0; i < totvert; i++) {
if (ss->filter_cache->sharpen_factor[i] > max_factor) {
@@ -402,6 +416,31 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss)
ss->filter_cache->sharpen_factor[i] *= max_factor;
ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]);
}
+
+ /* Smooth the calculated factors and directions to remove high frecuency detail. */
+ for (int smooth_iterations = 0;
+ smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations;
+ smooth_iterations++) {
+ for (int i = 0; i < totvert; i++) {
+ float direction_avg[3] = {0.0f, 0.0f, 0.0f};
+ float sharpen_avg = 0;
+ int total = 0;
+
+ SculptVertexNeighborIter ni;
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]);
+ sharpen_avg += ss->filter_cache->sharpen_factor[ni.index];
+ total++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (total > 0) {
+ mul_v3_v3fl(
+ ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / (float)total);
+ ss->filter_cache->sharpen_factor[i] = sharpen_avg / (float)total;
+ }
+ }
+ }
}
static void mesh_filter_surface_smooth_displace_task_cb(
@@ -566,7 +605,14 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent
if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) {
ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio");
+ ss->filter_cache->sharpen_intensify_detail_strength = RNA_float_get(
+ op->ptr, "sharpen_intensify_detail_strength");
+ ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get(
+ op->ptr, "sharpen_curvature_smooth_iterations");
+
ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor");
+ ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN(
+ totvert, 3 * sizeof(float), "sharpen detail direction");
mesh_filter_sharpen_init_factors(ss);
}
@@ -642,4 +688,24 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot)
"How much smoothing is applied to polished surfaces",
0.0f,
1.0f);
+
+ RNA_def_float(ot->srna,
+ "sharpen_intensify_detail_strength",
+ 0.0f,
+ 0.0f,
+ 10.0f,
+ "Intensify Details",
+ "How much creases and valleys are intensified",
+ 0.0f,
+ 1.0f);
+
+ RNA_def_int(ot->srna,
+ "sharpen_curvature_smooth_iterations",
+ 0,
+ 0,
+ 10,
+ "Curvature Smooth Iterations",
+ "How much smooth the resulting shape is, ignoring high frequency details",
+ 0,
+ 10);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 6a989ffea7e..74feaa8ca00 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -97,6 +97,9 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]);
float SCULPT_vertex_mask_get(struct SculptSession *ss, int index);
const float *SCULPT_vertex_color_get(SculptSession *ss, int index);
+const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index);
+void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]);
+
#define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
typedef struct SculptVertexNeighborIter {
/* Storage */
@@ -347,7 +350,6 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim);
void SCULPT_cloth_simulation_limits_draw(const uint gpuattr,
const struct Brush *brush,
- const float obmat[4][4],
const float location[3],
const float normal[3],
const float rds,
@@ -393,6 +395,7 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain);
/* Multiplane Scrape Brush. */
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
+ Brush *brush,
SculptSession *ss,
const float outline_col[3],
const float outline_alpha);
@@ -905,7 +908,10 @@ typedef struct FilterCache {
/* Sharpen mesh filter. */
float sharpen_smooth_ratio;
+ float sharpen_intensify_detail_strength;
+ int sharpen_curvature_smooth_iterations;
float *sharpen_factor;
+ float (*sharpen_detail_directions)[3];
/* unmasked nodes */
PBVHNode **nodes;
diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
index 60483cc168d..bc493a036f0 100644
--- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c
@@ -174,7 +174,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
ARegion *region = CTX_wm_region(C);
float prevclick_f[2];
copy_v2_v2(prevclick_f, op->customdata);
- int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]};
+ const int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]};
int len = (int)len_v2v2_int(prevclick, event->mval);
len = abs(len);
int mask_speed = RNA_int_get(op->ptr, "mask_speed");
diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
index b52036d753c..e47a94dff90 100644
--- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
+++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c
@@ -47,7 +47,6 @@
#include "paint_intern.h"
#include "sculpt_intern.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
#include "GPU_matrix.h"
@@ -376,7 +375,7 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
/* Calculate the final left and right scrape planes. */
float plane_no[3];
float plane_no_rot[3];
- float y_axis[3] = {0.0f, 1.0f, 0.0f};
+ const float y_axis[3] = {0.0f, 1.0f, 0.0f};
float mat_inv[4][4];
invert_m4_m4(mat_inv, mat);
@@ -400,10 +399,15 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
}
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
+ Brush *brush,
SculptSession *ss,
const float outline_col[3],
const float outline_alpha)
{
+ if (!(brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW)) {
+ return;
+ }
+
float local_mat_inv[4][4];
invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat);
GPU_matrix_mul(local_mat_inv);
@@ -414,11 +418,11 @@ void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,
float offset = ss->cache->radius * 0.25f;
- float p[3] = {0.0f, 0.0f, ss->cache->radius};
- float y_axis[3] = {0.0f, 1.0f, 0.0f};
+ const float p[3] = {0.0f, 0.0f, ss->cache->radius};
+ const float y_axis[3] = {0.0f, 1.0f, 0.0f};
float p_l[3];
float p_r[3];
- float area_center[3] = {0.0f, 0.0f, 0.0f};
+ const float area_center[3] = {0.0f, 0.0f, 0.0f};
rotate_v3_v3v3fl(p_r, p, y_axis, DEG2RADF((angle + 180) * 0.5f));
rotate_v3_v3v3fl(p_l, p, y_axis, DEG2RADF(-(angle + 180) * 0.5f));
diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
index f01a914fdd3..00a59949130 100644
--- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c
+++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c
@@ -255,7 +255,7 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
return;
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
float area_no[3];
float mat[4][4];
@@ -468,7 +468,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
}
}
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
SculptThreadedTaskData data = {
.sd = sd,
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index dc556fa1945..8a288877d43 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -1006,7 +1006,7 @@ void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br
static void sculpt_pose_do_translate_deform(SculptSession *ss, Brush *brush)
{
SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
pose_solve_translate_chain(ik_chain, ss->cache->grab_delta);
}
@@ -1031,8 +1031,10 @@ static void sculpt_pose_do_scale_deform(SculptSession *ss, Brush *brush)
copy_v3_v3(ik_target, ss->cache->true_location);
add_v3_v3(ik_target, ss->cache->grab_delta);
- /* Solve the IK for the first segment to include rotation as part of scale. */
- pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED);
+ /* Solve the IK for the first segment to include rotation as part of scale if enabled. */
+ if (!(brush->flag2 & BRUSH_POSE_USE_LOCK_ROTATION)) {
+ pose_solve_ik_chain(ik_chain, ik_target, brush->flag2 & BRUSH_POSE_IK_ANCHORED);
+ }
float scale[3];
copy_v3_fl(scale, sculpt_pose_get_scale_from_grab_delta(ss, ik_target));
@@ -1047,7 +1049,7 @@ static void sculpt_pose_do_twist_deform(SculptSession *ss, Brush *brush)
/* Calculate the maximum roll. 0.02 radians per pixel works fine. */
float roll = (ss->cache->initial_mouse[0] - ss->cache->mouse[0]) * ss->cache->bstrength * 0.02f;
- BKE_curvemapping_initialize(brush->curve);
+ BKE_curvemapping_init(brush->curve);
pose_solve_roll_chain(ik_chain, brush, roll);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 4b3df2dfea2..be509f4aed6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -488,7 +488,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
op->customdata = data;
- BKE_curvemapping_initialize(ts->uvsculpt->paint.brush->curve);
+ BKE_curvemapping_init(ts->uvsculpt->paint.brush->curve);
if (data) {
int counter = 0, i;
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 079cee290ae..db55eff8284 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -60,7 +60,7 @@
/* ******************** default callbacks for action space ***************** */
-static SpaceLink *action_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *action_create(const ScrArea *area, const Scene *scene)
{
SpaceAction *saction;
ARegion *region;
@@ -863,7 +863,7 @@ void ED_spacetype_action(void)
st->spaceid = SPACE_ACTION;
strncpy(st->name, "Action", BKE_ST_MAXNAME);
- st->new = action_new;
+ st->create = action_create;
st->free = action_free;
st->init = action_init;
st->duplicate = action_duplicate;
diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c
index 3ae203b563b..1656a76e2d4 100644
--- a/source/blender/editors/space_api/spacetypes.c
+++ b/source/blender/editors/space_api/spacetypes.c
@@ -280,7 +280,7 @@ void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
void ED_spacetype_xxx(void);
/* allocate and init some vars */
-static SpaceLink *xxx_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *xxx_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
return NULL;
}
@@ -324,7 +324,7 @@ void ED_spacetype_xxx(void)
st.spaceid = SPACE_VIEW3D;
- st.new = xxx_new;
+ st.create = xxx_create;
st.free = xxx_free;
st.init = xxx_init;
st.duplicate = xxx_duplicate;
diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c
index 16256f6c97e..5885d3dcbb0 100644
--- a/source/blender/editors/space_buttons/buttons_context.c
+++ b/source/blender/editors/space_buttons/buttons_context.c
@@ -101,7 +101,7 @@ static PointerRNA *get_pointer_type(ButsContextPath *path, StructRNA *type)
/************************* Creating the Path ************************/
-static int buttons_context_path_scene(ButsContextPath *path)
+static bool buttons_context_path_scene(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -162,14 +162,14 @@ static int buttons_context_path_world(ButsContextPath *path)
return 0;
}
-static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
+static bool buttons_context_path_linestyle(ButsContextPath *path, wmWindow *window)
{
FreestyleLineStyle *linestyle;
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) linestyle, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_FreestyleLineStyle)) {
- return 1;
+ return true;
}
/* if we have a view layer, use the lineset's linestyle */
if (buttons_context_path_view_layer(path, window)) {
@@ -178,24 +178,24 @@ static int buttons_context_path_linestyle(ButsContextPath *path, wmWindow *windo
if (linestyle) {
RNA_id_pointer_create(&linestyle->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a linestyle possible */
- return 0;
+ return false;
}
-static int buttons_context_path_object(ButsContextPath *path)
+static bool buttons_context_path_object(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) object, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Object)) {
- return 1;
+ return true;
}
if (!RNA_struct_is_a(ptr->type, &RNA_ViewLayer)) {
- return 0;
+ return false;
}
ViewLayer *view_layer = ptr->data;
@@ -205,58 +205,58 @@ static int buttons_context_path_object(ButsContextPath *path)
RNA_id_pointer_create(&ob->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
/* no path to a object possible */
- return 0;
+ return false;
}
-static int buttons_context_path_data(ButsContextPath *path, int type)
+static bool buttons_context_path_data(ButsContextPath *path, int type)
{
Object *ob;
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a data, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Curve) &&
(type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Light) && (type == -1 || type == OB_LAMP)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_LightProbe) && (type == -1 || type == OB_LIGHTPROBE)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) {
- return 1;
+ return true;
}
if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) {
- return 1;
+ return true;
}
/* try to get an object in the path, no pinning supported here */
if (buttons_context_path_object(path)) {
@@ -266,15 +266,15 @@ static int buttons_context_path_data(ButsContextPath *path, int type)
RNA_id_pointer_create(ob->data, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to data possible */
- return 0;
+ return false;
}
-static int buttons_context_path_modifier(ButsContextPath *path)
+static bool buttons_context_path_modifier(ButsContextPath *path)
{
Object *ob;
@@ -291,14 +291,14 @@ static int buttons_context_path_modifier(ButsContextPath *path)
OB_HAIR,
OB_POINTCLOUD,
OB_VOLUME)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-static int buttons_context_path_shaderfx(ButsContextPath *path)
+static bool buttons_context_path_shaderfx(ButsContextPath *path)
{
Object *ob;
@@ -306,14 +306,14 @@ static int buttons_context_path_shaderfx(ButsContextPath *path)
ob = path->ptr[path->len - 1].data;
if (ob && ELEM(ob->type, OB_GPENCIL)) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-static int buttons_context_path_material(ButsContextPath *path)
+static bool buttons_context_path_material(ButsContextPath *path)
{
Object *ob;
PointerRNA *ptr = &path->ptr[path->len - 1];
@@ -321,7 +321,7 @@ static int buttons_context_path_material(ButsContextPath *path)
/* if we already have a (pinned) material, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Material)) {
- return 1;
+ return true;
}
/* if we have an object, use the object material slot */
if (buttons_context_path_object(path)) {
@@ -331,15 +331,15 @@ static int buttons_context_path_material(ButsContextPath *path)
ma = BKE_object_material_get(ob, ob->actcol);
RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a material possible */
- return 0;
+ return false;
}
-static int buttons_context_path_bone(ButsContextPath *path)
+static bool buttons_context_path_bone(ButsContextPath *path)
{
bArmature *arm;
EditBone *edbo;
@@ -353,29 +353,29 @@ static int buttons_context_path_bone(ButsContextPath *path)
edbo = arm->act_edbone;
RNA_pointer_create(&arm->id, &RNA_EditBone, edbo, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
else {
if (arm->act_bone) {
RNA_pointer_create(&arm->id, &RNA_Bone, arm->act_bone, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
}
/* no path to a bone possible */
- return 0;
+ return false;
}
-static int buttons_context_path_pose_bone(ButsContextPath *path)
+static bool buttons_context_path_pose_bone(ButsContextPath *path)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
/* if we already have a (pinned) PoseBone, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
- return 1;
+ return true;
}
/* if we have an armature, get the active bone */
@@ -384,7 +384,7 @@ static int buttons_context_path_pose_bone(ButsContextPath *path)
bArmature *arm = ob->data; /* path->ptr[path->len-1].data - works too */
if (ob->type != OB_ARMATURE || arm->edbo) {
- return 0;
+ return false;
}
if (arm->act_bone) {
@@ -392,16 +392,16 @@ static int buttons_context_path_pose_bone(ButsContextPath *path)
if (pchan) {
RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
}
/* no path to a bone possible */
- return 0;
+ return false;
}
-static int buttons_context_path_particle(ButsContextPath *path)
+static bool buttons_context_path_particle(ButsContextPath *path)
{
Object *ob;
ParticleSystem *psys;
@@ -409,7 +409,7 @@ static int buttons_context_path_particle(ButsContextPath *path)
/* if we already have (pinned) particle settings, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) {
- return 1;
+ return true;
}
/* if we have an object, get the active particle system */
if (buttons_context_path_object(path)) {
@@ -420,15 +420,15 @@ static int buttons_context_path_particle(ButsContextPath *path)
RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a particle system possible */
- return 0;
+ return false;
}
-static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
+static bool buttons_context_path_brush(const bContext *C, ButsContextPath *path)
{
Scene *scene;
Brush *br = NULL;
@@ -436,7 +436,7 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
/* if we already have a (pinned) brush, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Brush)) {
- return 1;
+ return true;
}
/* if we have a scene, use the toolsettings brushes */
if (buttons_context_path_scene(path)) {
@@ -452,32 +452,32 @@ static int buttons_context_path_brush(const bContext *C, ButsContextPath *path)
RNA_id_pointer_create((ID *)br, &path->ptr[path->len]);
path->len++;
- return 1;
+ return true;
}
}
/* no path to a brush possible */
- return 0;
+ return false;
}
-static int buttons_context_path_texture(const bContext *C,
- ButsContextPath *path,
- ButsContextTexture *ct)
+static bool buttons_context_path_texture(const bContext *C,
+ ButsContextPath *path,
+ ButsContextTexture *ct)
{
PointerRNA *ptr = &path->ptr[path->len - 1];
ID *id;
if (!ct) {
- return 0;
+ return false;
}
/* if we already have a (pinned) texture, we're done */
if (RNA_struct_is_a(ptr->type, &RNA_Texture)) {
- return 1;
+ return true;
}
if (!ct->user) {
- return 0;
+ return false;
}
id = ct->user->id;
@@ -502,7 +502,7 @@ static int buttons_context_path_texture(const bContext *C,
path->len++;
}
- return 1;
+ return true;
}
#ifdef WITH_FREESTYLE
@@ -531,7 +531,7 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie
}
#endif
-static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
+static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
/* Note we don't use CTX_data here, instead we get it from the window.
* Otherwise there is a loop reading the context that we are setting. */
@@ -626,27 +626,27 @@ static int buttons_context_path(const bContext *C, ButsContextPath *path, int ma
found = buttons_context_path_pose_bone(path);
break;
default:
- found = 0;
+ found = false;
break;
}
return found;
}
-static int buttons_shading_context(const bContext *C, int mainb)
+static bool buttons_shading_context(const bContext *C, int mainb)
{
wmWindow *window = CTX_wm_window(C);
ViewLayer *view_layer = WM_window_get_active_view_layer(window);
Object *ob = OBACT(view_layer);
if (ELEM(mainb, BCONTEXT_MATERIAL, BCONTEXT_WORLD, BCONTEXT_TEXTURE)) {
- return 1;
+ return true;
}
if (mainb == BCONTEXT_DATA && ob && ELEM(ob->type, OB_LAMP, OB_CAMERA)) {
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static int buttons_shading_new_context(const bContext *C, int flag)
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 733f344fbc6..a062b178fc8 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -52,7 +52,9 @@
#include "buttons_intern.h" /* own include */
-/********************** context_menu operator *********************/
+/* -------------------------------------------------------------------- */
+/** \name Context Menu Operator
+ * \{ */
static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
@@ -67,17 +69,21 @@ static int context_menu_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven
void BUTTONS_OT_context_menu(wmOperatorType *ot)
{
- /* identifiers */
+ /* Identifiers. */
ot->name = "Context Menu";
ot->description = "Display properties editor context_menu";
ot->idname = "BUTTONS_OT_context_menu";
- /* api callbacks */
+ /* Callbacks. */
ot->invoke = context_menu_invoke;
ot->poll = ED_operator_buttons_active;
}
-/********************** filebrowse operator *********************/
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name File Browse Operator
+ * \{ */
typedef struct FileBrowseOp {
PointerRNA ptr;
@@ -101,7 +107,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
str = RNA_string_get_alloc(op->ptr, path_prop, NULL, 0);
- /* add slash for directories, important for some properties */
+ /* Add slash for directories, important for some properties. */
if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
const bool is_relative = RNA_boolean_get(op->ptr, "relative_path");
id = fbo->ptr.owner_id;
@@ -110,7 +116,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
BLI_path_abs(path, id ? ID_BLEND_PATH(bmain, id) : BKE_main_blendfile_path(bmain));
if (BLI_is_dir(path)) {
- /* do this first so '//' isnt converted to '//\' on windows */
+ /* Do this first so '//' isnt converted to '//\' on windows. */
BLI_path_slash_ensure(path);
if (is_relative) {
BLI_strncpy(path, str, FILE_MAX);
@@ -139,7 +145,7 @@ static int file_browse_exec(bContext *C, wmOperator *op)
ED_undo_push(C, undostr);
}
- /* special, annoying exception, filesel on redo panel [#26618] */
+ /* Special annoying exception, filesel on redo panel [#26618]. */
{
wmOperator *redo_op = WM_operator_last_redo(C);
if (redo_op) {
@@ -187,8 +193,8 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
str = RNA_property_string_get_alloc(&ptr, prop, NULL, 0, NULL);
- /* useful yet irritating feature, Shift+Click to open the file
- * Alt+Click to browse a folder in the OS's browser */
+ /* Useful yet irritating feature, Shift+Click to open the file
+ * Alt+Click to browse a folder in the OS's browser. */
if (event->shift || event->alt) {
wmOperatorType *ot = WM_operatortype_find("WM_OT_path_open", true);
PointerRNA props_ptr;
@@ -219,13 +225,13 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
fbo->is_userdef = is_userdef;
op->customdata = fbo;
- /* normally ED_fileselect_get_params would handle this but we need to because of stupid
- * user-prefs exception - campbell */
+ /* Normally ED_fileselect_get_params would handle this but we need to because of stupid
+ * user-prefs exception. - campbell */
if ((prop_relpath = RNA_struct_find_property(op->ptr, "relative_path"))) {
if (!RNA_property_is_set(op->ptr, prop_relpath)) {
bool is_relative = (U.flag & USER_RELPATHS) != 0;
- /* while we want to follow the defaults,
+ /* While we want to follow the defaults,
* we better not switch existing paths relative/absolute state. */
if (str[0]) {
is_relative = BLI_path_is_rel(str);
@@ -235,7 +241,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
is_relative = false;
}
- /* annoying exception!, if we're dealing with the user prefs, default relative to be off */
+ /* Annoying exception!, if we're dealing with the user prefs, default relative to be off. */
RNA_property_boolean_set(op->ptr, prop_relpath, is_relative);
}
}
@@ -250,21 +256,21 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void BUTTONS_OT_file_browse(wmOperatorType *ot)
{
- /* identifiers */
+ /* Identifiers. */
ot->name = "Accept";
ot->description =
"Open a file browser, Hold Shift to open the file, Alt to browse containing directory";
ot->idname = "BUTTONS_OT_file_browse";
- /* api callbacks */
+ /* Callbacks. */
ot->invoke = file_browse_invoke;
ot->exec = file_browse_exec;
ot->cancel = file_browse_cancel;
- /* conditional undo based on button flag */
+ /* Conditional undo based on button flag. */
ot->flag = 0;
- /* properties */
+ /* Properties. */
WM_operator_properties_filesel(ot,
0,
FILE_SPECIAL,
@@ -274,7 +280,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot)
FILE_SORT_ALPHA);
}
-/* second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY */
+/* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */
void BUTTONS_OT_directory_browse(wmOperatorType *ot)
{
/* identifiers */
@@ -300,3 +306,5 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot)
FILE_DEFAULTDISPLAY,
FILE_SORT_ALPHA);
}
+
+/** \} */
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index ac59bb245f3..dc34e56dc92 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -35,6 +35,7 @@
#include "BKE_screen.h"
#include "BKE_shader_fx.h"
+#include "ED_buttons.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_view3d.h" /* To draw toolbar UI. */
@@ -49,13 +50,11 @@
#include "UI_resources.h"
-#include "GPU_glew.h"
-
#include "buttons_intern.h" /* own include */
/* ******************** default callbacks for buttons space ***************** */
-static SpaceLink *buttons_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *buttons_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceProperties *sbuts;
@@ -139,6 +138,98 @@ static void buttons_main_region_init(wmWindowManager *wm, ARegion *region)
WM_event_add_keymap_handler(&region->handlers, keymap);
}
+/**
+ * Fills an array with the tab context values for the properties editor. -1 signals a separator.
+ *
+ * \return The total number of items in the array returned.
+ */
+int ED_buttons_tabs_list(SpaceProperties *sbuts, int *context_tabs_array)
+{
+ int length = 0;
+ if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
+ context_tabs_array[length] = BCONTEXT_TOOL;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
+ context_tabs_array[length] = BCONTEXT_RENDER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
+ context_tabs_array[length] = BCONTEXT_OUTPUT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
+ context_tabs_array[length] = BCONTEXT_VIEW_LAYER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
+ context_tabs_array[length] = BCONTEXT_SCENE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
+ context_tabs_array[length] = BCONTEXT_WORLD;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
+ context_tabs_array[length] = BCONTEXT_OBJECT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
+ context_tabs_array[length] = BCONTEXT_MODIFIER;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
+ context_tabs_array[length] = BCONTEXT_SHADERFX;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
+ context_tabs_array[length] = BCONTEXT_PARTICLE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
+ context_tabs_array[length] = BCONTEXT_PHYSICS;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
+ context_tabs_array[length] = BCONTEXT_CONSTRAINT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
+ context_tabs_array[length] = BCONTEXT_DATA;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
+ context_tabs_array[length] = BCONTEXT_BONE;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
+ context_tabs_array[length] = BCONTEXT_BONE_CONSTRAINT;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
+ context_tabs_array[length] = BCONTEXT_MATERIAL;
+ length++;
+ }
+ if (length != 0) {
+ context_tabs_array[length] = -1;
+ length++;
+ }
+ if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
+ context_tabs_array[length] = BCONTEXT_TEXTURE;
+ length++;
+ }
+
+ return length;
+}
+
static void buttons_main_region_layout_properties(const bContext *C,
SpaceProperties *sbuts,
ARegion *region)
@@ -618,7 +709,7 @@ void ED_spacetype_buttons(void)
st->spaceid = SPACE_PROPERTIES;
strncpy(st->name, "Buttons", BKE_ST_MAXNAME);
- st->new = buttons_new;
+ st->create = buttons_create;
st->free = buttons_free;
st->init = buttons_init;
st->duplicate = buttons_duplicate;
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index 71f75d96cb1..80ce07d39ef 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -273,7 +273,7 @@ typedef struct {
int marker_flag;
} MarkerUpdateCb;
-static void to_pixel_space(float r[2], float a[2], int width, int height)
+static void to_pixel_space(float r[2], const float a[2], int width, int height)
{
copy_v2_v2(r, a);
r[0] *= width;
diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c
index c3aca95910b..c7328ae9f8f 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_draw.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c
@@ -49,7 +49,9 @@
#include "clip_intern.h" /* own include */
-static void track_channel_color(MovieTrackingTrack *track, float default_color[3], float color[3])
+static void track_channel_color(MovieTrackingTrack *track,
+ const float default_color[3],
+ float color[3])
{
if (track->flag & TRACK_CUSTOMCOLOR) {
float bg[3];
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index d33f624063a..1d510d2989c 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -322,7 +322,7 @@ static void draw_movieclip_buffer(const bContext *C,
float zoomy)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
- int filter = GL_LINEAR;
+ bool use_filter = true;
int x, y;
/* find window pixel coordinates of origin */
@@ -340,10 +340,10 @@ static void draw_movieclip_buffer(const bContext *C,
/* non-scaled proxy shouldn't use filtering */
if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) {
- filter = GL_NEAREST;
+ use_filter = false;
}
- ED_draw_imbuf_ctx(C, ibuf, x, y, filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, use_filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
if (ibuf->planes == 32) {
GPU_blend(false);
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index 589831b1c45..ffd3241a30f 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -114,7 +114,7 @@ static void find_nearest_tracking_segment_cb(void *userdata,
float val)
{
MouseSelectUserData *data = userdata;
- float co[2] = {scene_framenr, val};
+ const float co[2] = {scene_framenr, val};
if (!clip_graph_value_visible(data->sc, value_source)) {
return;
@@ -151,7 +151,7 @@ static void find_nearest_tracking_knot_cb(void *userdata,
float val)
{
MouseSelectUserData *data = userdata;
- float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]};
+ const float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]};
float dist_sq = len_squared_v2(mdiff);
if (!clip_graph_value_visible(data->sc, value_source)) {
@@ -159,7 +159,7 @@ static void find_nearest_tracking_knot_cb(void *userdata,
}
if (data->marker == NULL || dist_sq < data->min_dist_sq) {
- float co[2] = {scene_framenr, val};
+ const float co[2] = {scene_framenr, val};
data->track = track;
data->marker = marker;
@@ -178,7 +178,7 @@ static void mouse_select_init_data(bContext *C, MouseSelectUserData *userdata, c
copy_v2_v2(userdata->mouse_co, co);
}
-static bool mouse_select_knot(bContext *C, float co[2], bool extend)
+static bool mouse_select_knot(bContext *C, const float co[2], bool extend)
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -236,7 +236,7 @@ static bool mouse_select_knot(bContext *C, float co[2], bool extend)
return false;
}
-static bool mouse_select_curve(bContext *C, float co[2], bool extend)
+static bool mouse_select_curve(bContext *C, const float co[2], bool extend)
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 9c251fb619a..d27b80efd40 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -56,7 +56,6 @@
#include "IMB_imbuf.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "WM_api.h"
@@ -238,7 +237,7 @@ static void clip_area_sync_frame_from_scene(ScrArea *area, Scene *scene)
/* ******************** default callbacks for clip space ***************** */
-static SpaceLink *clip_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *clip_create(const ScrArea *area, const Scene *scene)
{
ARegion *region;
SpaceClip *sc;
@@ -685,7 +684,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (main_visible) {
if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
@@ -697,7 +696,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag |= RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_main->handlers);
view_changed = true;
}
@@ -710,7 +709,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (properties_visible) {
if (region_properties && (region_properties->flag & RGN_FLAG_HIDDEN)) {
region_properties->flag &= ~RGN_FLAG_HIDDEN;
- region_properties->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_properties->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_properties && region_properties->alignment != RGN_ALIGN_RIGHT) {
@@ -721,7 +720,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_properties && !(region_properties->flag & RGN_FLAG_HIDDEN)) {
region_properties->flag |= RGN_FLAG_HIDDEN;
- region_properties->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_properties->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_properties->handlers);
view_changed = true;
}
@@ -734,7 +733,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (tools_visible) {
if (region_tools && (region_tools->flag & RGN_FLAG_HIDDEN)) {
region_tools->flag &= ~RGN_FLAG_HIDDEN;
- region_tools->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_tools->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_tools && region_tools->alignment != RGN_ALIGN_LEFT) {
@@ -745,7 +744,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_tools && !(region_tools->flag & RGN_FLAG_HIDDEN)) {
region_tools->flag |= RGN_FLAG_HIDDEN;
- region_tools->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_tools->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_tools->handlers);
view_changed = true;
}
@@ -758,7 +757,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (preview_visible) {
if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
view_changed = true;
}
@@ -770,7 +769,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag |= RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_preview->handlers);
view_changed = true;
}
@@ -783,7 +782,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
if (channels_visible) {
if (region_channels && (region_channels->flag & RGN_FLAG_HIDDEN)) {
region_channels->flag &= ~RGN_FLAG_HIDDEN;
- region_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_channels->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_channels && region_channels->alignment != RGN_ALIGN_LEFT) {
@@ -794,7 +793,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
else {
if (region_channels && !(region_channels->flag & RGN_FLAG_HIDDEN)) {
region_channels->flag |= RGN_FLAG_HIDDEN;
- region_channels->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_channels->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_channels->handlers);
view_changed = true;
}
@@ -805,7 +804,7 @@ static void clip_refresh(const bContext *C, ScrArea *area)
}
if (view_changed) {
- ED_area_initialize(wm, window, area);
+ ED_area_init(wm, window, area);
ED_area_tag_redraw(area);
}
@@ -1352,7 +1351,7 @@ void ED_spacetype_clip(void)
st->spaceid = SPACE_CLIP;
strncpy(st->name, "Clip", BKE_ST_MAXNAME);
- st->new = clip_new;
+ st->create = clip_create;
st->free = clip_free;
st->init = clip_init;
st->duplicate = clip_duplicate;
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 739701b5595..177a0bc2bcf 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -513,7 +513,7 @@ static bool slide_check_corners(float (*corners)[2])
{
int i, next, prev;
float cross = 0.0f;
- float p[2] = {0.0f, 0.0f};
+ const float p[2] = {0.0f, 0.0f};
if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) {
return false;
@@ -861,7 +861,7 @@ 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_OFFSET) {
- float d[2] = {dx, dy};
+ const float d[2] = {dx, dy};
for (int a = 0; a < data->track->markersnr; a++) {
add_v2_v2v2(data->track->markers[a].pos, data->old_markers[a], d);
}
@@ -940,7 +940,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
BKE_tracking_marker_clamp(data->marker, CLAMP_SEARCH_DIM);
}
else if (data->area == TRACK_AREA_SEARCH) {
- float d[2] = {dx, dy};
+ const float d[2] = {dx, dy};
add_v2_v2v2(data->min, data->old_search_min, d);
add_v2_v2v2(data->max, data->old_search_max, d);
}
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index b6f9ca9589f..80d0dd773b2 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -153,9 +153,9 @@ static float dist_to_rect(const float co[2],
const float max[2])
{
float d1, d2, d3, d4;
- float p[2] = {co[0] - pos[0], co[1] - pos[1]};
- float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]};
- float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]};
+ const float p[2] = {co[0] - pos[0], co[1] - pos[1]};
+ const float v1[2] = {min[0], min[1]}, v2[2] = {max[0], min[1]};
+ const float v3[2] = {max[0], max[1]}, v4[2] = {min[0], max[1]};
d1 = dist_squared_to_line_segment_v2(p, v1, v2);
d2 = dist_squared_to_line_segment_v2(p, v2, v3);
@@ -169,7 +169,7 @@ static float dist_to_rect(const float co[2],
static float dist_to_crns(const float co[2], const float pos[2], const float crns[4][2])
{
float d1, d2, d3, d4;
- float p[2] = {co[0] - pos[0], co[1] - pos[1]};
+ const float p[2] = {co[0] - pos[0], co[1] - pos[1]};
const float *v1 = crns[0], *v2 = crns[1];
const float *v3 = crns[2], *v4 = crns[3];
@@ -744,7 +744,9 @@ static int point_inside_ellipse(const float point[2],
return x * x + y * y < 1.0f;
}
-static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2])
+static int marker_inside_ellipse(MovieTrackingMarker *marker,
+ const float offset[2],
+ const float ellipse[2])
{
return point_inside_ellipse(marker->pos, offset, ellipse);
}
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index 3c62aeb1759..3a0125356f7 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -46,7 +46,7 @@
/* ******************** default callbacks for console space ***************** */
-static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *console_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceConsole *sconsole;
@@ -312,7 +312,7 @@ void ED_spacetype_console(void)
st->spaceid = SPACE_CONSOLE;
strncpy(st->name, "Console", BKE_ST_MAXNAME);
- st->new = console_new;
+ st->create = console_create;
st->free = console_free;
st->init = console_init;
st->duplicate = console_duplicate;
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 5150f6bed69..083d41747b3 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -300,9 +300,8 @@ static void file_draw_preview(uiBlock *block,
(float)yco,
imb->x,
imb->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
imb->rect,
scale,
scale,
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 45e45093238..e9ffd4583d7 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -518,7 +518,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
rect.ymin = rect.ymax = event->mval[1];
if (!ED_fileselect_layout_is_inside_pt(sfile->layout, &region->v2d, rect.xmin, rect.ymin)) {
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
}
if (sfile && sfile->params) {
@@ -1697,6 +1697,19 @@ static int file_exec(bContext *C, wmOperator *exec_op)
return OPERATOR_FINISHED;
}
+static int file_exec_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ ARegion *region = CTX_wm_region(C);
+ SpaceFile *sfile = CTX_wm_space_file(C);
+
+ if (!ED_fileselect_layout_is_inside_pt(
+ sfile->layout, &region->v2d, event->mval[0], event->mval[1])) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+
+ return file_exec(C, op);
+}
+
void FILE_OT_execute(struct wmOperatorType *ot)
{
PropertyRNA *prop;
@@ -1707,6 +1720,7 @@ void FILE_OT_execute(struct wmOperatorType *ot)
ot->idname = "FILE_OT_execute";
/* api callbacks */
+ ot->invoke = file_exec_invoke;
ot->exec = file_exec;
ot->poll = file_operator_poll;
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 43939b9ff54..f520f91b89b 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -91,7 +91,7 @@ static ARegion *file_tool_props_region_ensure(ScrArea *area, ARegion *region_pre
/* ******************** default callbacks for file space ***************** */
-static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *file_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceFile *sfile;
@@ -235,7 +235,7 @@ static void file_ensure_valid_region_state(bContext *C,
ARegion *region_ui = BKE_area_find_region_type(area, RGN_TYPE_UI);
ARegion *region_props = BKE_area_find_region_type(area, RGN_TYPE_TOOL_PROPS);
ARegion *region_execute = BKE_area_find_region_type(area, RGN_TYPE_EXECUTE);
- bool needs_init = false; /* To avoid multiple ED_area_initialize() calls. */
+ bool needs_init = false; /* To avoid multiple ED_area_init() calls. */
/* If there's an file-operation, ensure we have the option and execute region */
if (sfile->op && (region_props == NULL)) {
@@ -261,7 +261,7 @@ static void file_ensure_valid_region_state(bContext *C,
}
if (needs_init) {
- ED_area_initialize(wm, win, area);
+ ED_area_init(wm, win, area);
}
}
@@ -693,7 +693,7 @@ void ED_spacetype_file(void)
st->spaceid = SPACE_FILE;
strncpy(st->name, "File", BKE_ST_MAXNAME);
- st->new = file_new;
+ st->create = file_create;
st->free = file_free;
st->init = file_init;
st->exit = file_exit;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 68fdef54a53..90fe95c6818 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -1487,7 +1487,7 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent
dgo->area = CTX_wm_area(C);
dgo->region = CTX_wm_region(C);
- /* initialise percentage so that it will have the correct value before the first mouse move. */
+ /* Initialize percentage so that it will have the correct value before the first mouse move. */
decimate_mouse_update_percentage(dgo, op, event);
decimate_draw_status_header(op, dgo);
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index b1d995a7a0b..a4f76384cc6 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -64,7 +64,7 @@
/* ******************** default callbacks for ipo space ***************** */
-static SpaceLink *graph_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *graph_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
SpaceGraph *sipo;
@@ -838,7 +838,7 @@ void ED_spacetype_ipo(void)
st->spaceid = SPACE_GRAPH;
strncpy(st->name, "Graph", BKE_ST_MAXNAME);
- st->new = graph_new;
+ st->create = graph_create;
st->free = graph_free;
st->init = graph_init;
st->duplicate = graph_duplicate;
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index a7fa7709c51..f70589ac5f1 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -168,9 +168,9 @@ void ED_image_draw_info(Scene *scene,
uchar green[3] = {0, 255, 0};
uchar blue[3] = {100, 100, 255};
#else
- uchar red[3] = {255, 255, 255};
- uchar green[3] = {255, 255, 255};
- uchar blue[3] = {255, 255, 255};
+ const uchar red[3] = {255, 255, 255};
+ const uchar green[3] = {255, 255, 255};
+ const uchar blue[3] = {255, 255, 255};
#endif
float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0;
float col[4], finalcol[4];
@@ -465,23 +465,22 @@ void ED_image_draw_info(Scene *scene,
static void sima_draw_zbuf_pixels(
float x1, float y1, int rectx, int recty, const int *rect, float zoomx, float zoomy)
{
- float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
/* Slowwww */
- int *recti = MEM_mallocN(rectx * recty * sizeof(int), "temp");
+ float *rectf = MEM_mallocN(rectx * recty * sizeof(float), "temp");
for (int a = rectx * recty - 1; a >= 0; a--) {
/* zbuffer values are signed, so we need to shift color range */
- recti[a] = rect[a] * 0.5f + 0.5f;
+ rectf[a] = rect[a] * 0.5f + 0.5f;
}
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR);
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, x1, y1, rectx, recty, GL_RED, GL_INT, GL_NEAREST, recti, zoomx, zoomy, NULL);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GPU_R16F, false, rectf, zoomx, zoomy, NULL);
- MEM_freeN(recti);
+ MEM_freeN(rectf);
}
static void sima_draw_zbuffloat_pixels(Scene *scene,
@@ -495,7 +494,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
{
float bias, scale, *rectf, clip_end;
int a;
- float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
if (scene->camera && scene->camera->type == OB_CAMERA) {
bias = ((Camera *)scene->camera->data)->clip_start;
@@ -526,8 +525,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene,
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(
- &state, x1, y1, rectx, recty, GL_RED, GL_FLOAT, GL_NEAREST, rectf, zoomx, zoomy, NULL);
+ immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_R16F, false, rectf, zoomx, zoomy, NULL);
MEM_freeN(rectf);
}
@@ -612,8 +610,7 @@ static void draw_image_buffer(const bContext *C,
/* If RGBA display with color management */
if ((sima_flag & (SI_SHOW_R | SI_SHOW_G | SI_SHOW_B | SI_SHOW_ALPHA)) == 0) {
- ED_draw_imbuf_ctx_clipping(
- C, ibuf, x, y, GL_NEAREST, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
+ ED_draw_imbuf_ctx_clipping(C, ibuf, x, y, false, 0, 0, clip_max_x, clip_max_y, zoomx, zoomy);
}
else {
float shuffle[4] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -649,9 +646,8 @@ static void draw_image_buffer(const bContext *C,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
display_buffer,
0,
0,
@@ -780,18 +776,8 @@ static void draw_image_paint_helpers(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
- immDrawPixelsTex(&state,
- x,
- y,
- ibuf->x,
- ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- display_buffer,
- zoomx,
- zoomy,
- col);
+ immDrawPixelsTex(
+ &state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col);
GPU_blend(false);
@@ -812,7 +798,7 @@ static void draw_udim_tile_grid(uint pos_attr,
{
float x1, y1;
UI_view2d_view_to_region_fl(&region->v2d, x, y, &x1, &y1);
- int gridpos[5][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
+ const int gridpos[5][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
for (int i = 0; i < 4; i++) {
immAttr3fv(color_attr, color);
immVertex2f(pos_attr, x1 + gridpos[i][0] * stepx, y1 + gridpos[i][1] * stepy);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 4e410d35df0..1a98ec0e7c1 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -69,7 +69,6 @@
#include "DEG_depsgraph.h"
-#include "GPU_draw.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -2769,7 +2768,7 @@ static int image_invert_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
/* force GPU reupload, all image is invalid */
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -2860,7 +2859,7 @@ static int image_scale_exec(bContext *C, wmOperator *op)
ED_image_undo_push_end();
/* force GPU reupload, all image is invalid */
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
DEG_id_tag_update(&ima->id, 0);
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
@@ -3715,7 +3714,7 @@ static void draw_fill_tile(PointerRNA *ptr, uiLayout *layout)
uiItemR(col[1], ptr, "float", 0, NULL, ICON_NONE);
}
-static void initialize_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile)
+static void tile_fill_init(PointerRNA *ptr, Image *ima, ImageTile *tile)
{
ImageUser iuser;
BKE_imageuser_default(&iuser);
@@ -3828,7 +3827,7 @@ static int tile_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
}
ImageTile *tile = BLI_findlink(&ima->tiles, ima->active_tile_index);
- initialize_fill_tile(op->ptr, ima, tile);
+ tile_fill_init(op->ptr, ima, tile);
RNA_int_set(op->ptr, "number", next_number);
RNA_int_set(op->ptr, "count", 1);
@@ -3974,7 +3973,7 @@ static int tile_fill_exec(bContext *C, wmOperator *op)
static int tile_fill_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- initialize_fill_tile(op->ptr, CTX_data_edit_image(C), NULL);
+ tile_fill_init(op->ptr, CTX_data_edit_image(C), NULL);
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X);
}
diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c
index e0c44c3a0ba..27b84307f7d 100644
--- a/source/blender/editors/space_image/image_undo.c
+++ b/source/blender/editors/space_image/image_undo.c
@@ -60,8 +60,6 @@
#include "ED_undo.h"
#include "ED_util.h"
-#include "GPU_draw.h"
-
#include "WM_api.h"
static CLG_LogRef LOG = {"ed.image.undo"};
@@ -295,7 +293,8 @@ static void ptile_restore_runtime_list(ListBase *paint_tiles)
SWAP(uint *, ptile->rect.uint, tmpibuf->rect);
}
- GPU_free_image(image); /* force OpenGL reload (maybe partial update will operate better?) */
+ BKE_image_free_gputextures(
+ image); /* force OpenGL reload (maybe partial update will operate better?) */
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
}
@@ -570,7 +569,7 @@ static void uhandle_restore_list(ListBase *undo_handles, bool use_init)
if (changed) {
BKE_image_mark_dirty(image, ibuf);
- GPU_free_image(image); /* force OpenGL reload */
+ BKE_image_free_gputextures(image); /* force OpenGL reload */
if (ibuf->rect_float) {
ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index ac0dbba1606..c01bc01588e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -116,7 +116,7 @@ static void image_user_refresh_scene(const bContext *C, SpaceImage *sima)
/* ******************** default callbacks for image space ***************** */
-static SpaceLink *image_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *image_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceImage *simage;
@@ -1093,7 +1093,7 @@ void ED_spacetype_image(void)
st->spaceid = SPACE_IMAGE;
strncpy(st->name, "Image", BKE_ST_MAXNAME);
- st->new = image_new;
+ st->create = image_create;
st->free = image_free;
st->init = image_init;
st->duplicate = image_duplicate;
diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c
index 6c818257ec7..72533b88406 100644
--- a/source/blender/editors/space_info/info_draw.c
+++ b/source/blender/editors/space_info/info_draw.c
@@ -270,12 +270,12 @@ void *info_text_pick(const SpaceInfo *sinfo,
int info_textview_height(const SpaceInfo *sinfo, const ARegion *region, const ReportList *reports)
{
- int mval[2] = {INT_MAX, INT_MAX};
+ const int mval[2] = {INT_MAX, INT_MAX};
return info_textview_main__internal(sinfo, region, reports, false, mval, NULL, NULL);
}
void info_textview_main(const SpaceInfo *sinfo, const ARegion *region, const ReportList *reports)
{
- int mval[2] = {INT_MAX, INT_MAX};
+ const int mval[2] = {INT_MAX, INT_MAX};
info_textview_main__internal(sinfo, region, reports, true, mval, NULL, NULL);
}
diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c
index 836830916ed..b9153ec0cbd 100644
--- a/source/blender/editors/space_info/space_info.c
+++ b/source/blender/editors/space_info/space_info.c
@@ -53,7 +53,7 @@
/* ******************** default callbacks for info space ***************** */
-static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *info_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceInfo *sinfo;
@@ -287,7 +287,7 @@ void ED_spacetype_info(void)
st->spaceid = SPACE_INFO;
strncpy(st->name, "Info", BKE_ST_MAXNAME);
- st->new = info_new;
+ st->create = info_create;
st->free = info_free;
st->init = info_init;
st->duplicate = info_duplicate;
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index eee8b989cc2..93a79d9a2bc 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -264,7 +264,7 @@ static bool textview_draw_string(TextViewDrawState *tds,
if (tds->sel[0] != tds->sel[1]) {
textview_step_sel(tds, -final_offset);
- int pos[2] = {tds->xy[0], line_bottom};
+ const int pos[2] = {tds->xy[0], line_bottom};
textview_draw_sel(s, pos, len, tds, bg_sel);
}
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 96599fd92a7..97939a93d01 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -378,7 +378,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin
}
/* helper call to setup dashed-lines for strip outlines */
-static uint nla_draw_use_dashed_outlines(float color[4], bool muted)
+static uint nla_draw_use_dashed_outlines(const float color[4], bool muted)
{
/* Note that we use dashed shader here, and make it draw solid lines if not muted... */
uint shdr_pos = GPU_vertformat_attr_add(
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index b09536e0621..7bbfe451eed 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -57,7 +57,7 @@
/* ******************** default callbacks for nla space ***************** */
-static SpaceLink *nla_new(const ScrArea *area, const Scene *scene)
+static SpaceLink *nla_create(const ScrArea *area, const Scene *scene)
{
ARegion *region;
SpaceNla *snla;
@@ -608,7 +608,7 @@ void ED_spacetype_nla(void)
st->spaceid = SPACE_NLA;
strncpy(st->name, "NLA", BKE_ST_MAXNAME);
- st->new = nla_new;
+ st->create = nla_create;
st->free = nla_free;
st->init = nla_init;
st->duplicate = nla_duplicate;
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 01883f1c086..207f67aed1b 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3678,9 +3678,8 @@ void draw_nodespace_back_pix(const bContext *C,
y,
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
display_buffer,
snode->zoom,
snode->zoom,
@@ -3693,12 +3692,12 @@ void draw_nodespace_back_pix(const bContext *C,
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
GPU_blend(false);
}
else {
- ED_draw_imbuf_ctx(C, ibuf, x, y, GL_NEAREST, snode->zoom, snode->zoom);
+ ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom);
}
if (cache_handle) {
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 22b549cbd5d..3fd0b0a5a58 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -947,9 +947,8 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
draw_rect.ymin,
preview->xsize,
preview->ysize,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_LINEAR,
+ GPU_RGBA8,
+ true,
preview->rect,
scale,
scale,
@@ -987,7 +986,7 @@ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha)
else {
const float margin = 3.0f;
- float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 0.33f};
UI_draw_roundbox_aa(true,
rct->xmin - margin,
rct->ymin - margin,
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 7af64e75656..c88b6a1b297 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -1697,6 +1697,8 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
snode_notify(C, snode);
if (do_tag_update) {
snode_dag_update(C, snode);
@@ -1739,6 +1741,8 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
@@ -2739,7 +2743,7 @@ static int clear_viewer_border_exec(bContext *C, wmOperator *UNUSED(op))
void NODE_OT_clear_viewer_border(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Clear Viewer Border";
+ ot->name = "Clear Viewer Region";
ot->description = "Clear the boundaries for viewer operations";
ot->idname = "NODE_OT_clear_viewer_border";
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 3e898b7d400..a09c70b794a 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -670,6 +670,8 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
}
ntree->is_updating = false;
+ do_tag_update |= ED_node_is_simulation(snode);
+
ntreeUpdateTree(bmain, ntree);
snode_notify(C, snode);
if (do_tag_update) {
@@ -1002,7 +1004,7 @@ void NODE_OT_link_make(wmOperatorType *ot)
}
/* ********************** Cut Link operator ***************** */
-static bool cut_links_intersect(bNodeLink *link, float mcoords[][2], int tot)
+static bool cut_links_intersect(bNodeLink *link, const float mcoords[][2], int tot)
{
float coord_array[NODE_LINK_RESOL + 1][2];
int i, b;
@@ -1070,6 +1072,8 @@ static int cut_links_exec(bContext *C, wmOperator *op)
}
}
+ do_tag_update |= ED_node_is_simulation(snode);
+
if (found) {
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
snode_notify(C, snode);
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index d4adad3fc25..6d570001347 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -244,7 +244,7 @@ void snode_group_offset(SpaceNode *snode, float *x, float *y)
/* ******************** default callbacks for node space ***************** */
-static SpaceLink *node_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *node_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceNode *snode;
@@ -954,7 +954,7 @@ void ED_spacetype_node(void)
st->spaceid = SPACE_NODE;
strncpy(st->name, "Node", BKE_ST_MAXNAME);
- st->new = node_new;
+ st->create = node_create;
st->free = node_free;
st->init = node_init;
st->duplicate = node_duplicate;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index a45b415b629..4271eaded99 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2694,7 +2694,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle,
int ys,
const int num_elements)
{
- float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ const float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
float ufac = 0.25f * UI_UNIT_X;
float offset_x = (float)offsx + UI_UNIT_X * 0.35f;
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index aa1663dff01..8a78211f145 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -294,7 +294,7 @@ static void outliner_header_region_listener(wmWindow *UNUSED(win),
/* ******************** default callbacks for outliner space ***************** */
-static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *outliner_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceOutliner *soutliner;
@@ -407,7 +407,7 @@ void ED_spacetype_outliner(void)
st->spaceid = SPACE_OUTLINER;
strncpy(st->name, "Outliner", BKE_ST_MAXNAME);
- st->new = outliner_new;
+ st->create = outliner_create;
st->free = outliner_free;
st->init = outliner_init;
st->duplicate = outliner_duplicate;
diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c
index 343f35421a4..4d0c2b658c6 100644
--- a/source/blender/editors/space_script/space_script.c
+++ b/source/blender/editors/space_script/space_script.c
@@ -51,7 +51,7 @@
/* ******************** default callbacks for script space ***************** */
-static SpaceLink *script_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *script_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceScript *sscript;
@@ -179,7 +179,7 @@ void ED_spacetype_script(void)
st->spaceid = SPACE_SCRIPT;
strncpy(st->name, "Script", BKE_ST_MAXNAME);
- st->new = script_new;
+ st->create = script_create;
st->free = script_free;
st->init = script_init;
st->duplicate = script_duplicate;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 995e980aba0..0f4690c11d5 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1599,7 +1599,7 @@ static void sequencer_draw_display_buffer(const bContext *C,
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
- /* Format needs to be created prior to any immBindProgram call.
+ /* Format needs to be created prior to any immBindShader call.
* Do it here because OCIO binds it's own shader. */
eGPUTextureFormat format;
eGPUDataFormat data;
@@ -2169,7 +2169,7 @@ static void draw_cache_view(const bContext *C)
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT) {
stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT);
stripe_top = stripe_bot + stripe_ht;
- float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f};
+ const float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, scene->r.sfra, stripe_bot, scene->r.efra, stripe_top);
@@ -2188,7 +2188,7 @@ static void draw_cache_view(const bContext *C)
stripe_top = stripe_bot + stripe_ht;
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_RAW) {
- float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f};
+ const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
}
@@ -2197,7 +2197,7 @@ static void draw_cache_view(const bContext *C)
stripe_top = stripe_bot + stripe_ht;
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED) {
- float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f};
+ const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
}
@@ -2206,7 +2206,7 @@ static void draw_cache_view(const bContext *C)
stripe_bot = stripe_top - stripe_ht;
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_COMPOSITE) {
- float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f};
+ const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f};
immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index b2d0362602e..99d4c2d9f1a 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -666,74 +666,6 @@ int seq_effect_find_selected(Scene *scene,
/** \name Delete Utilities
* \{ */
-static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq)
-{
- Sequence *seq1, *seq2, *seq3;
-
- /* Try to find a replacement input sequence, and flag for later deletion if
- * no replacement can be found. */
-
- if (!seq) {
- return NULL;
- }
- if (!(seq->type & SEQ_TYPE_EFFECT)) {
- return ((seq->flag & SELECT) ? NULL : seq);
- }
- if (!(seq->flag & SELECT)) {
- /* Try to find replacement for effect inputs. */
- seq1 = del_seq_find_replace_recurs(scene, seq->seq1);
- seq2 = del_seq_find_replace_recurs(scene, seq->seq2);
- seq3 = del_seq_find_replace_recurs(scene, seq->seq3);
-
- if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) {
- /* Pass. */
- }
- else if (seq1 || seq2 || seq3) {
- seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3;
- seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3;
- seq->seq3 = (seq3) ? seq3 : (seq1) ? seq1 : seq2;
-
- BKE_sequencer_update_changed_seq_and_deps(scene, seq, 1, 1);
- }
- else {
- seq->flag |= SELECT; /* Mark for delete. */
- }
- }
-
- if (seq->flag & SELECT) {
- if ((seq1 = del_seq_find_replace_recurs(scene, seq->seq1))) {
- return seq1;
- }
- if ((seq2 = del_seq_find_replace_recurs(scene, seq->seq2))) {
- return seq2;
- }
- if ((seq3 = del_seq_find_replace_recurs(scene, seq->seq3))) {
- return seq3;
- }
- return NULL;
- }
- return seq;
-}
-
-static void del_seq_clear_modifiers_recurs(Scene *scene, Sequence *deleting_sequence)
-{
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *current_sequence;
-
- SEQP_BEGIN (ed, current_sequence) {
- if (!(current_sequence->flag & SELECT) && current_sequence != deleting_sequence) {
- SequenceModifierData *smd;
-
- for (smd = current_sequence->modifiers.first; smd; smd = smd->next) {
- if (smd->mask_sequence == deleting_sequence) {
- smd->mask_sequence = NULL;
- }
- }
- }
- }
- SEQ_END;
-}
-
static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short deleteall)
{
Sequence *seq, *seqn;
@@ -2586,61 +2518,20 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
Scene *scene = CTX_data_scene(C);
Editing *ed = BKE_sequencer_editing_get(scene, false);
Sequence *seq;
- MetaStack *ms;
- bool nothing_selected = true;
BKE_sequencer_prefetch_stop(scene);
- seq = BKE_sequencer_active_get(scene);
- if (seq && seq->flag & SELECT) { /* Avoid a loop since this is likely to be selected. */
- nothing_selected = false;
- }
- else {
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (seq->flag & SELECT) {
- nothing_selected = false;
- break;
- }
- }
- }
-
- if (nothing_selected) {
- return OPERATOR_FINISHED;
- }
-
- /* For effects and modifiers, try to find a replacement input. */
- for (seq = ed->seqbasep->first; seq; seq = seq->next) {
- if (!(seq->flag & SELECT)) {
- if ((seq->type & SEQ_TYPE_EFFECT)) {
- del_seq_find_replace_recurs(scene, seq);
- }
- }
- else {
- del_seq_clear_modifiers_recurs(scene, seq);
+ SEQP_BEGIN (scene->ed, seq) {
+ if (seq->flag & SELECT) {
+ BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq);
}
}
-
- /* Delete all selected strips. */
- recurs_del_seq_flag(scene, ed->seqbasep, SELECT, 0);
-
- /* Update lengths, etc. */
- seq = ed->seqbasep->first;
- while (seq) {
- BKE_sequence_calc(scene, seq);
- seq = seq->next;
- }
-
- /* Free parent metas. */
- ms = ed->metastack.last;
- while (ms) {
- BKE_sequence_calc(scene, ms->parseq);
- ms = ms->prev;
- }
+ SEQ_END;
+ BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
-
return OPERATOR_FINISHED;
}
@@ -3036,8 +2927,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
/* This moves strips from meta to parent, sating within same edit and no new strips are
- * allocated. If the UUID was unique already (as it should) it will stay unique. Nn need to
- * re-generate the UUIDs.*/
+ * allocated. If the UUID was unique already (as it should) it will stay unique.
+ * No need to re-generate the UUIDs. */
BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
BLI_listbase_clear(&last_seq->seqbase);
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 926752c6488..b8bb3e4d43b 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -86,7 +86,7 @@ static ARegion *sequencer_find_region(ScrArea *area, short type)
/* ******************** default callbacks for sequencer space ***************** */
-static SpaceLink *sequencer_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
SpaceSeq *sseq;
@@ -231,12 +231,12 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
case SEQ_VIEW_SEQUENCE:
if (region_main && (region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
view_changed = true;
}
if (region_preview && !(region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag |= RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_preview->handlers);
view_changed = true;
}
@@ -252,13 +252,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
case SEQ_VIEW_PREVIEW:
if (region_main && !(region_main->flag & RGN_FLAG_HIDDEN)) {
region_main->flag |= RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
WM_event_remove_handlers((bContext *)C, &region_main->handlers);
view_changed = true;
}
if (region_preview && (region_preview->flag & RGN_FLAG_HIDDEN)) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
view_changed = true;
}
@@ -281,13 +281,13 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
* 'full window' views before, though... Better than nothing. */
if (region_main->flag & RGN_FLAG_HIDDEN) {
region_main->flag &= ~RGN_FLAG_HIDDEN;
- region_main->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_main->v2d.flag &= ~V2D_IS_INIT;
region_preview->sizey = (int)(height - region_main->sizey);
view_changed = true;
}
if (region_preview->flag & RGN_FLAG_HIDDEN) {
region_preview->flag &= ~RGN_FLAG_HIDDEN;
- region_preview->v2d.flag &= ~V2D_IS_INITIALISED;
+ region_preview->v2d.flag &= ~V2D_IS_INIT;
region_preview->v2d.cur = region_preview->v2d.tot;
region_main->sizey = (int)(height - region_preview->sizey);
view_changed = true;
@@ -312,7 +312,7 @@ static void sequencer_refresh(const bContext *C, ScrArea *area)
}
if (view_changed) {
- ED_area_initialize(wm, window, area);
+ ED_area_init(wm, window, area);
ED_area_tag_redraw(area);
}
}
@@ -852,7 +852,7 @@ void ED_spacetype_sequencer(void)
st->spaceid = SPACE_SEQ;
strncpy(st->name, "Sequencer", BKE_ST_MAXNAME);
- st->new = sequencer_new;
+ st->create = sequencer_create;
st->free = sequencer_free;
st->init = sequencer_init;
st->duplicate = sequencer_duplicate;
diff --git a/source/blender/editors/space_statusbar/space_statusbar.c b/source/blender/editors/space_statusbar/space_statusbar.c
index 34d7f8b0216..ae56b111360 100644
--- a/source/blender/editors/space_statusbar/space_statusbar.c
+++ b/source/blender/editors/space_statusbar/space_statusbar.c
@@ -42,7 +42,7 @@
/* ******************** default callbacks for statusbar space ******************** */
-static SpaceLink *statusbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *statusbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceStatusBar *sstatusbar;
@@ -158,7 +158,7 @@ void ED_spacetype_statusbar(void)
st->spaceid = SPACE_STATUSBAR;
strncpy(st->name, "Status Bar", BKE_ST_MAXNAME);
- st->new = statusbar_new;
+ st->create = statusbar_create;
st->free = statusbar_free;
st->init = statusbar_init;
st->duplicate = statusbar_duplicate;
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index a2af99ee9f9..f6d00ec94bf 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -53,7 +53,7 @@
/* ******************** default callbacks for text space ***************** */
-static SpaceLink *text_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *text_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceText *stext;
@@ -445,7 +445,7 @@ void ED_spacetype_text(void)
st->spaceid = SPACE_TEXT;
strncpy(st->name, "Text", BKE_ST_MAXNAME);
- st->new = text_new;
+ st->create = text_create;
st->free = text_free;
st->init = text_init;
st->duplicate = text_duplicate;
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 24c55e60513..74cf3c866d3 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -55,7 +55,7 @@ int text_do_suggest_select(SpaceText *st, ARegion *region)
TextLine *tmp;
int l, x, y, w, h, i;
int tgti, *top;
- int mval[2] = {0, 0};
+ const int mval[2] = {0, 0};
if (!st || !st->text) {
return 0;
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 6be436cffb5..201f9dae5d5 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -2587,7 +2587,7 @@ static void text_scroll_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
TextScroll *tsc = op->customdata;
- int mval[2] = {event->x, event->y};
+ const int mval[2] = {event->x, event->y};
text_update_character_width(st);
diff --git a/source/blender/editors/space_topbar/space_topbar.c b/source/blender/editors/space_topbar/space_topbar.c
index d06c567988d..dc357cdd355 100644
--- a/source/blender/editors/space_topbar/space_topbar.c
+++ b/source/blender/editors/space_topbar/space_topbar.c
@@ -52,7 +52,7 @@
/* ******************** default callbacks for topbar space ***************** */
-static SpaceLink *topbar_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
+static SpaceLink *topbar_create(const ScrArea *UNUSED(area), const Scene *UNUSED(scene))
{
ARegion *region;
SpaceTopBar *stopbar;
@@ -250,7 +250,7 @@ void ED_spacetype_topbar(void)
st->spaceid = SPACE_TOPBAR;
strncpy(st->name, "Top Bar", BKE_ST_MAXNAME);
- st->new = topbar_new;
+ st->create = topbar_create;
st->free = topbar_free;
st->init = topbar_init;
st->duplicate = topbar_duplicate;
diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c
index 9eae722d5c8..0242bb4fe24 100644
--- a/source/blender/editors/space_userpref/space_userpref.c
+++ b/source/blender/editors/space_userpref/space_userpref.c
@@ -45,7 +45,7 @@
/* ******************** default callbacks for userpref space ***************** */
-static SpaceLink *userpref_new(const ScrArea *area, const Scene *UNUSED(scene))
+static SpaceLink *userpref_create(const ScrArea *area, const Scene *UNUSED(scene))
{
ARegion *region;
SpaceUserPref *spref;
@@ -115,7 +115,7 @@ static void userpref_main_region_init(wmWindowManager *wm, ARegion *region)
{
/* do not use here, the properties changed in userprefs do a system-wide refresh,
* then scroller jumps back */
- /* region->v2d.flag &= ~V2D_IS_INITIALISED; */
+ /* region->v2d.flag &= ~V2D_IS_INIT; */
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HIDE;
@@ -235,7 +235,7 @@ void ED_spacetype_userpref(void)
st->spaceid = SPACE_USERPREF;
strncpy(st->name, "Userpref", BKE_ST_MAXNAME);
- st->new = userpref_new;
+ st->create = userpref_create;
st->free = userpref_free;
st->init = userpref_init;
st->duplicate = userpref_duplicate;
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index f17d7ccd136..1ffa653372c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -69,7 +69,7 @@ static const float cosval[CIRCLE_RESOL] = {
0.82076344, 0.91895781, 0.97952994, 1.00000000,
};
-static void circball_array_fill(float verts[CIRCLE_RESOL][3],
+static void circball_array_fill(const float verts[CIRCLE_RESOL][3],
const float cent[3],
float rad,
const float tmat[4][4])
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index c88303daa16..e5ba27cef07 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -260,7 +260,7 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *area)
/* ******************** default callbacks for view3d space ***************** */
-static SpaceLink *view3d_new(const ScrArea *UNUSED(area), const Scene *scene)
+static SpaceLink *view3d_create(const ScrArea *UNUSED(area), const Scene *scene)
{
ARegion *region;
View3D *v3d;
@@ -616,11 +616,12 @@ static void view3d_lightcache_update(bContext *C)
return;
}
- WM_operator_properties_create(&op_ptr, "SCENE_OT_light_cache_bake");
+ wmOperatorType *ot = WM_operatortype_find("SCENE_OT_light_cache_bake", true);
+ WM_operator_properties_create_ptr(&op_ptr, ot);
RNA_int_set(&op_ptr, "delay", 200);
RNA_enum_set_identifier(C, &op_ptr, "subset", "DIRTY");
- WM_operator_name_call(C, "SCENE_OT_light_cache_bake", WM_OP_INVOKE_DEFAULT, &op_ptr);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
WM_operator_properties_free(&op_ptr);
}
@@ -1610,7 +1611,7 @@ void ED_spacetype_view3d(void)
st->spaceid = SPACE_VIEW3D;
strncpy(st->name, "View3D", BKE_ST_MAXNAME);
- st->new = view3d_new;
+ st->create = view3d_create;
st->free = view3d_free;
st->init = view3d_init;
st->listener = space_view3d_listener;
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index 2e170126574..38784a5c79e 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -1071,7 +1071,7 @@ static void v3d_object_dimension_buts(bContext *C, uiLayout *layout, View3D *v3d
const float lim = FLT_MAX;
for (int i = 0; i < 3; i++) {
uiBut *but;
- char text[3] = {'X' + i, ':', '\0'};
+ const char text[3] = {'X' + i, ':', '\0'};
but = uiDefButF(block,
UI_BTYPE_NUM,
B_TRANSFORM_PANEL_DIMS,
@@ -1474,6 +1474,7 @@ static void v3d_editmetaball_buts(uiLayout *layout, Object *ob)
uiLayout *col;
if (!mball || !(mball->lastelem)) {
+ uiItemL(layout, IFACE_("Nothing selected"), ICON_NONE);
return;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 1af0cc074fc..0442a0f35c9 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -36,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_global.h"
+#include "BKE_image.h"
#include "BKE_key.h"
#include "BKE_layer.h"
#include "BKE_main.h"
@@ -74,7 +75,6 @@
#include "GPU_batch.h"
#include "GPU_batch_presets.h"
-#include "GPU_draw.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_immediate_util.h"
@@ -1620,7 +1620,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *region)
view3d_draw_view(C, region);
DRW_cache_free_old_batches(bmain);
- GPU_free_images_old(bmain);
+ BKE_image_free_old_gputextures(bmain);
GPU_pass_cache_garbage_collect();
/* XXX This is in order to draw UI batches with the DRW
@@ -1710,7 +1710,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
{
/* free images which can have changed on frame-change
* warning! can be slow so only free animated images - campbell */
- GPU_free_images_anim(G.main); /* XXX :((( */
+ BKE_image_free_anim_gputextures(G.main); /* XXX :((( */
}
GPU_matrix_push_projection();
@@ -1957,10 +1957,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
NULL);
if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
+ GPU_offscreen_read_pixels(ofs, GPU_DATA_FLOAT, ibuf->rect_float);
}
else if (ibuf->rect) {
- GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
+ GPU_offscreen_read_pixels(ofs, GPU_DATA_UNSIGNED_BYTE, ibuf->rect);
}
/* unbind */
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 19aa9cb203b..ac9d12cdd58 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -2500,7 +2500,10 @@ static bool viewdolly_offset_lock_check(bContext *C, wmOperator *op)
return false;
}
-static void view_dolly_to_vector_3d(ARegion *region, float orig_ofs[3], float dvec[3], float dfac)
+static void view_dolly_to_vector_3d(ARegion *region,
+ const float orig_ofs[3],
+ const float dvec[3],
+ float dfac)
{
RegionView3D *rv3d = region->regiondata;
madd_v3_v3v3fl(rv3d->ofs, orig_ofs, dvec, -(1.0f - dfac));
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
index 30212fcd9e5..e17993445df 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c
@@ -156,7 +156,7 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int
if (eve_test) {
BMVert *vert = (BMVert *)eve_test;
float vert_p_co[3], vert_co[3];
- float mval_f[2] = {UNPACK2(vc.mval)};
+ const float mval_f[2] = {UNPACK2(vc.mval)};
mul_v3_m4v3(vert_co, gz_ele->bases[base_index_vert]->object->obmat, vert->co);
ED_view3d_project(vc.region, vert_co, vert_p_co);
float len = len_v2v2(vert_p_co, mval_f);
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
index 59b2e378955..7799aba5c19 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c
@@ -909,7 +909,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz)
static int gizmo_ruler_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2])
{
RulerItem *ruler_item_pick = (RulerItem *)gz;
- float mval_fl[2] = {UNPACK2(mval)};
+ const float mval_fl[2] = {UNPACK2(mval)};
int co_index;
/* select and drag */
diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c
index b7219290654..a828dbc2ee0 100644
--- a/source/blender/editors/space_view3d/view3d_placement.c
+++ b/source/blender/editors/space_view3d/view3d_placement.c
@@ -246,7 +246,7 @@ static bool idp_poject_surface_normal(SnapObjectContext *snap_context,
/** \name Primitive Drawing (Cube, Cone, Cylinder...)
* \{ */
-static void draw_line_loop(float coords[][3], int coords_len, const float color[4])
+static void draw_line_loop(const float coords[][3], int coords_len, const float color[4])
{
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
@@ -279,7 +279,7 @@ static void draw_line_loop(float coords[][3], int coords_len, const float color[
GPU_blend(false);
}
-static void draw_line_pairs(float coords_a[][3],
+static void draw_line_pairs(const float coords_a[][3],
float coords_b[][3],
int coords_len,
const float color[4])
@@ -321,7 +321,7 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4])
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
- int edges[12][2] = {
+ const int edges[12][2] = {
/* First side. */
{0, 1},
{1, 2},
@@ -507,7 +507,7 @@ static void draw_circle_in_quad(const float v1[2],
float theta = ((2.0f * M_PI) * ((float)i / (float)resolution)) + 0.01f;
float x = cosf(theta);
float y = sinf(theta);
- float pt[2] = {x, y};
+ const float pt[2] = {x, y};
float w[4];
barycentric_weights_v2_quad(UNPACK4(quad), pt, w);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index c10a88af146..c790a8659ee 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -778,7 +778,7 @@ void ED_view3d_project(const struct ARegion *region, const float world[3], float
{
// viewport is set up to make coordinates relative to the region, not window
RegionView3D *rv3d = region->regiondata;
- int viewport[4] = {0, 0, region->winx, region->winy};
+ const int viewport[4] = {0, 0, region->winx, region->winy};
GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
}
@@ -787,8 +787,8 @@ bool ED_view3d_unproject(
const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
{
RegionView3D *rv3d = region->regiondata;
- int viewport[4] = {0, 0, region->winx, region->winy};
- float region_co[3] = {regionx, regiony, regionz};
+ const int viewport[4] = {0, 0, region->winx, region->winy};
+ const float region_co[3] = {regionx, regiony, regionz};
return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world);
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 64447015bdc..9490c807989 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -97,7 +97,6 @@
#include "UI_interface.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "DEG_depsgraph.h"
@@ -3336,12 +3335,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
FOREACH_OBJECT_IN_MODE_END;
}
else { /* No edit-mode, unified for bones and objects. */
- if (vc.obact && vc.obact->mode & OB_MODE_SCULPT) {
- /* XXX, this is not selection, could be it's own operator. */
- changed_multi = ED_sculpt_mask_box_select(
- C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false);
- }
- else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
+ if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
changed_multi = do_paintface_box_select(&vc, wm_userdata, &rect, sel_op);
}
else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 4e73a2be17e..a264e1560c6 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -1499,7 +1499,7 @@ void ED_view3d_from_m4(const float mat[4][4], float ofs[3], float quat[4], const
*/
void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist)
{
- float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
+ const float iviewquat[4] = {-quat[0], quat[1], quat[2], quat[3]};
float dvec[3] = {0.0f, 0.0f, dist};
quat_to_mat4(mat, iviewquat);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 66efa5b5de3..ff9673a4262 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -50,7 +50,6 @@
#include "UI_resources.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_select.h"
#include "GPU_state.h"
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 64167b83655..2cc41097070 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -387,7 +387,7 @@ static bool walk_floor_distance_get(RegionView3D *rv3d,
const float dvec[3],
float *r_distance)
{
- float ray_normal[3] = {0, 0, -1}; /* down */
+ const float ray_normal[3] = {0, 0, -1}; /* down */
float ray_start[3];
float r_location[3];
float r_normal_dummy[3];
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index bc00dd8e221..1917d9463f4 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -80,6 +80,7 @@ typedef struct TransSnap {
bool snap_self;
bool peel;
bool snap_spatial_grid;
+ bool use_backface_culling;
char status;
/* Snapped Element Type (currently for objects only). */
char snapElem;
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index e15239f37d4..d0e37f22236 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -388,7 +388,7 @@ void transform_constraint_snap_axis_to_face(const TransInfo *t,
* Return true if the 2x axis are both aligned when projected into the view.
* In this case, we can't usefully project the cursor onto the plane.
*/
-static bool isPlaneProjectionViewAligned(const TransInfo *t, float plane[4])
+static bool isPlaneProjectionViewAligned(const TransInfo *t, const float plane[4])
{
const float eps = 0.001f;
float view_to_plane[3];
diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c
index 0eb12aeabed..84885dd8c49 100644
--- a/source/blender/editors/transform/transform_convert_gpencil.c
+++ b/source/blender/editors/transform/transform_convert_gpencil.c
@@ -104,7 +104,7 @@ void createTransGPencil(bContext *C, TransInfo *t)
/* initialize falloff curve */
if (is_multiedit) {
- BKE_curvemapping_initialize(ts->gp_sculpt.cur_falloff);
+ BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
}
/* First Pass: Count the number of data-points required for the strokes,
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index ad426713719..573f4550fec 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -754,7 +754,8 @@ void createTransEditVerts(TransInfo *t)
if (tc->use_mirror_axis_any) {
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
bool use_select = (t->flag & T_PROP_EDIT) == 0;
- bool mirror_axis[3] = {tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
+ const bool mirror_axis[3] = {
+ tc->use_mirror_axis_x, tc->use_mirror_axis_y, tc->use_mirror_axis_z};
editmesh_mirror_data_calc(em, use_select, use_topology, mirror_axis, &mirror_data);
if (mirror_data.vert_map) {
@@ -1033,8 +1034,10 @@ static void mesh_customdatacorrect_free_cb(struct TransInfo *UNUSED(t),
# define FACE_SUBSTITUTE_INDEX INT_MIN
-/* Search for a neighboring face with area and preferably without selected vertex.
- * Used to replace arealess faces in customdata correction. */
+/**
+ * Search for a neighboring face with area and preferably without selected vertex.
+ * Used to replace area-less faces in custom-data correction.
+ */
static BMFace *mesh_customdatacorrect_find_best_face_substitute(BMFace *f)
{
BMFace *best_face = NULL;
diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c
index dacdb72806c..11cde6a9038 100644
--- a/source/blender/editors/transform/transform_gizmo_2d.c
+++ b/source/blender/editors/transform/transform_gizmo_2d.c
@@ -350,8 +350,8 @@ static void gizmo2d_xform_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup
ptr = WM_gizmo_operator_set(ggd->cage, 0, ot_translate, NULL);
RNA_boolean_set(ptr, "release_confirm", 1);
- bool constraint_x[3] = {1, 0, 0};
- bool constraint_y[3] = {0, 1, 0};
+ const bool constraint_x[3] = {1, 0, 0};
+ const bool constraint_y[3] = {0, 1, 0};
ptr = WM_gizmo_operator_set(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X, ot_resize, NULL);
PropertyRNA *prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
@@ -484,7 +484,7 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
ARegion *region = CTX_wm_region(C);
GizmoGroup2D *ggd = gzgroup->customdata;
float origin[3] = {UNPACK2(ggd->origin), 0.0f};
- float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f};
+ const float origin_aa[3] = {UNPACK2(ggd->origin), 0.0f};
gizmo2d_origin_to_region(region, origin);
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index 3878103fa4e..6155042f555 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -2053,7 +2053,7 @@ static void WIDGETGROUP_xform_cage_setup(const bContext *UNUSED(C), wmGizmoGroup
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
for (int z = 0; z < 3; z++) {
- bool constraint[3] = {x != 1, y != 1, z != 1};
+ const bool constraint[3] = {x != 1, y != 1, z != 1};
ptr = WM_gizmo_operator_set(gz, i, ot_resize, NULL);
if (prop_release_confirm == NULL) {
prop_release_confirm = RNA_struct_find_property(ptr, "release_confirm");
diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
index 7f6f3e53bc3..ae7cda0bd03 100644
--- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
@@ -213,7 +213,7 @@ static void gizmo_mesh_extrude_setup(const bContext *C, wmGizmoGroup *gzgroup)
PointerRNA macroptr = RNA_pointer_get(ptr, "TRANSFORM_OT_translate");
RNA_boolean_set(&macroptr, "release_confirm", true);
- bool constraint[3] = {0, 0, 0};
+ const bool constraint[3] = {0, 0, 0};
RNA_boolean_set_array(&macroptr, "constraint_axis", constraint);
}
diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c
index 38d49ab5efd..495c21bc755 100644
--- a/source/blender/editors/transform/transform_mode.c
+++ b/source/blender/editors/transform/transform_mode.c
@@ -178,7 +178,7 @@ static void protectedRotateBits(short protectflag, float eul[3], const float old
/* this function only does the delta rotation */
/* axis-angle is usually internally stored as quats... */
static void protectedAxisAngleBits(
- short protectflag, float axis[3], float *angle, float oldAxis[3], float oldAngle)
+ short protectflag, float axis[3], float *angle, const float oldAxis[3], float oldAngle)
{
/* check that protection flags are set */
if ((protectflag & (OB_LOCK_ROTX | OB_LOCK_ROTY | OB_LOCK_ROTZ | OB_LOCK_ROTW)) == 0) {
@@ -896,7 +896,7 @@ void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR])
*
* \note this is a tricky area, before making changes see: T29633, T42444
*/
-static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3])
+static void TransMat3ToSize(const float mat[3][3], const float smat[3][3], float size[3])
{
float rmat[3][3];
diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c
index 2c2253630c0..80a5b307a91 100644
--- a/source/blender/editors/transform/transform_mode_bbone_resize.c
+++ b/source/blender/editors/transform/transform_mode_bbone_resize.c
@@ -87,7 +87,10 @@ static void headerBoneSize(TransInfo *t, const float vec[3], char str[UI_MAX_DRA
}
}
-static void ElementBoneSize(TransInfo *t, TransDataContainer *tc, TransData *td, float mat[3][3])
+static void ElementBoneSize(TransInfo *t,
+ TransDataContainer *tc,
+ TransData *td,
+ const float mat[3][3])
{
float tmat[3][3], smat[3][3], oldy;
float sizemat[3][3];
diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c
index 4a648a77fe1..1886f95beae 100644
--- a/source/blender/editors/transform/transform_mode_edge_slide.c
+++ b/source/blender/editors/transform/transform_mode_edge_slide.c
@@ -534,7 +534,7 @@ static EdgeSlideData *createEdgeSlideVerts_double_side(TransInfo *t, TransDataCo
int sv_tot;
int *sv_table; /* BMVert -> sv_array index */
EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
- float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ const float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
int numsel, i, loop_nr;
bool use_occlude_geometry = false;
View3D *v3d = NULL;
@@ -894,7 +894,7 @@ static EdgeSlideData *createEdgeSlideVerts_single_side(TransInfo *t, TransDataCo
int sv_tot;
int *sv_table; /* BMVert -> sv_array index */
EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld");
- float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
+ const float mval[2] = {(float)t->mval[0], (float)t->mval[1]};
int loop_nr;
bool use_occlude_geometry = false;
View3D *v3d = NULL;
diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c
index fa33c1550e7..e508a1fa4c2 100644
--- a/source/blender/editors/transform/transform_mode_shear.c
+++ b/source/blender/editors/transform/transform_mode_shear.c
@@ -164,7 +164,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *td = tc->data;
for (i = 0; i < tc->data_len; i++, td++) {
- const float *center, *co;
+ const float *center;
if (td->flag & TD_SKIP) {
continue;
}
@@ -178,19 +178,15 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
if (is_local_center) {
center = td->center;
- co = td->loc;
}
else {
center = tc->center_local;
- co = td->center;
}
- sub_v3_v3v3(vec, co, center);
-
+ sub_v3_v3v3(vec, td->iloc, center);
mul_m3_v3(tmat, vec);
-
add_v3_v3(vec, center);
- sub_v3_v3(vec, co);
+ sub_v3_v3(vec, td->iloc);
if (t->options & CTX_GPENCIL_STROKES) {
/* grease pencil multiframe falloff */
diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c
index b396317ba7c..38537194af3 100644
--- a/source/blender/editors/transform/transform_mode_vert_slide.c
+++ b/source/blender/editors/transform/transform_mode_vert_slide.c
@@ -126,7 +126,7 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
{
/* Active object may have no selected vertices. */
VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
- float mval_fl[2] = {UNPACK2(mval)};
+ const float mval_fl[2] = {UNPACK2(mval)};
TransDataVertSlideVert *sv;
/* set the vertex to use as a reference for the mouse direction 'curr_sv_index' */
@@ -153,8 +153,8 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2])
static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2])
{
VertSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data;
- float imval_fl[2] = {UNPACK2(t->mouse.imval)};
- float mval_fl[2] = {UNPACK2(mval)};
+ const float imval_fl[2] = {UNPACK2(t->mouse.imval)};
+ const float mval_fl[2] = {UNPACK2(mval)};
float dir[3];
TransDataVertSlideVert *sv;
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2943c3cb8ea..a700dd320b7 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -37,6 +37,7 @@
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_object.h"
+#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "RNA_access.h"
@@ -100,6 +101,24 @@ int BIF_snappingSupported(Object *obedit)
}
#endif
+static bool snap_use_backface_culling(const TransInfo *t)
+{
+ BLI_assert(t->spacetype == SPACE_VIEW3D);
+ View3D *v3d = t->view;
+ if ((v3d->shading.type == OB_SOLID) && (v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING)) {
+ return true;
+ }
+ if (v3d->shading.type == OB_RENDER &&
+ (t->scene->display.shading.flag & V3D_SHADING_BACKFACE_CULLING) &&
+ BKE_scene_uses_blender_workbench(t->scene)) {
+ return true;
+ }
+ if (t->settings->snap_flag & SCE_SNAP_BACKFACE_CULLING) {
+ return true;
+ }
+ return false;
+}
+
bool validSnap(const TransInfo *t)
{
return (t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT) ||
@@ -315,8 +334,7 @@ void applyProject(TransInfo *t)
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
.use_occlusion_test = false,
- .use_backface_culling = (t->scene->toolsettings->snap_flag &
- SCE_SNAP_BACKFACE_CULLING) != 0,
+ .use_backface_culling = t->tsnap.use_backface_culling,
},
mval_fl,
NULL,
@@ -601,6 +619,7 @@ static void initSnappingMode(TransInfo *t)
if (t->spacetype == SPACE_VIEW3D) {
if (t->tsnap.object_context == NULL) {
+ t->tsnap.use_backface_culling = snap_use_backface_culling(t);
t->tsnap.object_context = ED_transform_snap_object_context_create_view3d(
t->scene, 0, t->region, t->view);
@@ -1120,13 +1139,12 @@ short snapObjectsTransform(
return ED_transform_snap_object_project_view3d_ex(
t->tsnap.object_context,
t->depsgraph,
- t->scene->toolsettings->snap_mode,
+ t->settings->snap_mode,
&(const struct SnapObjectParams){
.snap_select = t->tsnap.modeSelect,
.use_object_edit_cage = (t->flag & T_EDIT) != 0,
- .use_occlusion_test = t->scene->toolsettings->snap_mode != SCE_SNAP_MODE_FACE,
- .use_backface_culling = (t->scene->toolsettings->snap_flag &
- SCE_SNAP_BACKFACE_CULLING) != 0,
+ .use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE,
+ .use_backface_culling = t->tsnap.use_backface_culling,
},
mval,
target,
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index eb14c5bec28..50b7c6d147b 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -1214,7 +1214,7 @@ static void cb_mlooptri_edges_get(const int index, int v_index[3], const BVHTree
const MLoopTri *lt = &data->looptri[index];
for (int j = 2, j_next = 0; j_next < 3; j = j_next++) {
const MEdge *ed = &medge[mloop[lt->tri[j]].e];
- uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
+ const uint tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
if (ELEM(ed->v1, tri_edge[0], tri_edge[1]) && ELEM(ed->v2, tri_edge[0], tri_edge[1])) {
// printf("real edge found\n");
v_index[j] = mloop[lt->tri[j]].e;
@@ -1302,11 +1302,11 @@ static bool test_projected_edge_dist(const struct DistProjectedAABBPrecalc *prec
* \{ */
typedef void (*Nearest2DGetVertCoCallback)(const int index, const float **co, void *data);
-typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, int v_index[2], void *data);
-typedef void (*Nearest2DGetTriVertsCallback)(const int index, int v_index[3], void *data);
+typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const int v_index[2], void *data);
+typedef void (*Nearest2DGetTriVertsCallback)(const int index, const int v_index[3], void *data);
/* Equal the previous one */
-typedef void (*Nearest2DGetTriEdgesCallback)(const int index, int e_index[3], void *data);
-typedef void (*Nearest2DCopyVertNoCallback)(const int index, float r_no[3], void *data);
+typedef void (*Nearest2DGetTriEdgesCallback)(const int index, const int e_index[3], void *data);
+typedef void (*Nearest2DCopyVertNoCallback)(const int index, const float r_no[3], void *data);
typedef struct Nearest2dUserData {
void *userdata;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 3c747a29361..384da6fb931 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -26,6 +26,8 @@
#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
+#include "BLT_translation.h"
+
#include "BKE_context.h"
#include "BKE_scene.h"
#include "BKE_unit.h"
@@ -277,8 +279,12 @@ static bool editstr_insert_at_cursor(NumInput *n, const char *buf, const int buf
return true;
}
-bool user_string_to_number(
- bContext *C, const char *str, const UnitSettings *unit, int type, double *r_value)
+bool user_string_to_number(bContext *C,
+ const char *str,
+ const UnitSettings *unit,
+ int type,
+ const char *error_prefix,
+ double *r_value)
{
#ifdef WITH_PYTHON
double unit_scale = BKE_scene_unit_scale(unit, type, 1.0);
@@ -288,10 +294,10 @@ bool user_string_to_number(
bUnit_ReplaceString(
str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type);
- return BPY_execute_string_as_number(C, NULL, str_unit_convert, true, r_value);
+ return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value);
}
- int success = BPY_execute_string_as_number(C, NULL, str, true, r_value);
+ int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value);
*r_value *= bUnit_PreferredInputUnitScalar(unit, type);
*r_value /= unit_scale;
return success;
@@ -573,7 +579,8 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
Scene *sce = CTX_data_scene(C);
double val;
- int success = user_string_to_number(C, n->str, &sce->unit, n->unit_type[idx], &val);
+ int success = user_string_to_number(
+ C, n->str, &sce->unit, n->unit_type[idx], IFACE_("Numeric input evaluation"), &val);
if (success) {
n->val[idx] = (float)val;
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index daa31869a11..7455004ccb8 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -116,6 +116,7 @@ void UV_OT_sphere_project(struct wmOperatorType *ot);
void UV_OT_unwrap(struct wmOperatorType *ot);
void UV_OT_rip(struct wmOperatorType *ot);
void UV_OT_stitch(struct wmOperatorType *ot);
+void UV_OT_smart_project(struct wmOperatorType *ot);
/* uvedit_path.c */
void UV_OT_shortest_path_pick(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 532061e3dc1..956c094c19b 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2094,6 +2094,7 @@ void ED_operatortypes_uvedit(void)
WM_operatortype_append(UV_OT_reset);
WM_operatortype_append(UV_OT_sphere_project);
WM_operatortype_append(UV_OT_unwrap);
+ WM_operatortype_append(UV_OT_smart_project);
WM_operatortype_append(UV_OT_reveal);
WM_operatortype_append(UV_OT_hide);
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index a4ee9a294fe..8e079dcac94 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -497,7 +497,7 @@ static void p_chart_uv_translate(PChart *chart, const float trans[2])
}
}
-static void p_chart_uv_transform(PChart *chart, float mat[2][2])
+static void p_chart_uv_transform(PChart *chart, const float mat[2][2])
{
PVert *v;
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
index 07bec2da1ae..421e58b1cb5 100644
--- a/source/blender/editors/uvedit/uvedit_rip.c
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -538,23 +538,22 @@ static bool uv_rip_pairs_loop_change_sides_test(BMLoop *l_switch,
if (count_a + count_b == 4) {
return count_a > count_b;
}
- else {
- const float angle_a_before = uv_rip_pairs_calc_uv_angle(
- l_switch, side_a, aspect_y, cd_loop_uv_offset);
- const float angle_b_before = uv_rip_pairs_calc_uv_angle(
- l_target, side_b, aspect_y, cd_loop_uv_offset);
- UL(l_switch)->side = side_b;
+ const float angle_a_before = uv_rip_pairs_calc_uv_angle(
+ l_switch, side_a, aspect_y, cd_loop_uv_offset);
+ const float angle_b_before = uv_rip_pairs_calc_uv_angle(
+ l_target, side_b, aspect_y, cd_loop_uv_offset);
- const float angle_a_after = uv_rip_pairs_calc_uv_angle(
- l_switch, side_a, aspect_y, cd_loop_uv_offset);
- const float angle_b_after = uv_rip_pairs_calc_uv_angle(
- l_target, side_b, aspect_y, cd_loop_uv_offset);
+ UL(l_switch)->side = side_b;
- UL(l_switch)->side = side_a;
+ const float angle_a_after = uv_rip_pairs_calc_uv_angle(
+ l_switch, side_a, aspect_y, cd_loop_uv_offset);
+ const float angle_b_after = uv_rip_pairs_calc_uv_angle(
+ l_target, side_b, aspect_y, cd_loop_uv_offset);
- return fabsf(angle_a_before - angle_b_before) > fabsf(angle_a_after - angle_b_after);
- }
+ UL(l_switch)->side = side_a;
+
+ return fabsf(angle_a_before - angle_b_before) > fabsf(angle_a_after - angle_b_after);
}
/**
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index f649ee528d4..f3ea7456c38 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -323,7 +323,10 @@ static int getNumOfIslandUvs(UvElementMap *elementMap, int island)
return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island];
}
-static void stitch_uv_rotate(float mat[2][2], float medianPoint[2], float uv[2], float aspect)
+static void stitch_uv_rotate(const float mat[2][2],
+ const float medianPoint[2],
+ float uv[2],
+ float aspect)
{
float uv_rotation_result[2];
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 6fcfb0e0bfc..49f11cd6a74 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -35,7 +35,10 @@
#include "DNA_scene_types.h"
#include "BLI_alloca.h"
+#include "BLI_array.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_uvproject.h"
@@ -147,7 +150,13 @@ typedef struct UnwrapOptions {
/** Connectivity based on UV coordinates instead of seams. */
bool topology_from_uvs;
/** Only affect selected faces. */
- bool only_selected;
+ bool only_selected_faces;
+ /**
+ * Only affect selected UV's.
+ * \note Disable this for operations that don't run in the image-window.
+ * Unwrapping from the 3D view for example, where only 'only_selected_faces' should be used.
+ */
+ bool only_selected_uvs;
/** Fill holes to better preserve shape. */
bool fill_holes;
/** Correct for mapped image texture aspect ratio. */
@@ -299,7 +308,7 @@ static ParamHandle *construct_param_handle(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
- (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
+ (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
@@ -307,10 +316,12 @@ static ParamHandle *construct_param_handle(const Scene *scene,
bool is_loopsel = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- is_loopsel = true;
- break;
+ if (options->only_selected_uvs &&
+ (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) {
+ continue;
}
+ is_loopsel = true;
+ break;
}
if (is_loopsel == false) {
continue;
@@ -382,7 +393,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) ||
- (options->only_selected && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
+ (options->only_selected_faces && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
continue;
}
@@ -390,10 +401,12 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
bool is_loopsel = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- is_loopsel = true;
- break;
+ if (options->only_selected_uvs &&
+ (uvedit_uv_select_test(scene, l, cd_loop_uv_offset) == false)) {
+ continue;
}
+ is_loopsel = true;
+ break;
}
if (is_loopsel == false) {
continue;
@@ -571,7 +584,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
}
else {
if (BM_elem_flag_test(origFace, BM_ELEM_HIDDEN) ||
- (options->only_selected && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) {
+ (options->only_selected_faces && !BM_elem_flag_test(origFace, BM_ELEM_SELECT))) {
continue;
}
}
@@ -671,7 +684,8 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = true,
.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"),
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.correct_aspect = true,
};
@@ -933,7 +947,8 @@ static void uvedit_pack_islands(const Scene *scene, Object *ob, BMesh *bm)
{
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = false,
};
@@ -975,7 +990,8 @@ static int pack_islands_exec(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = true,
};
@@ -1040,7 +1056,8 @@ static int average_islands_scale_exec(bContext *C, wmOperator *UNUSED(op))
const UnwrapOptions options = {
.topology_from_uvs = true,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = false,
.correct_aspect = true,
};
@@ -1114,7 +1131,8 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit)
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
@@ -1330,7 +1348,7 @@ static void uv_map_rotation_matrix(float result[4][4],
float sideangledeg,
float radius)
{
- float offset[4] = {0};
+ const float offset[4] = {0};
uv_map_rotation_matrix_ex(result, rv3d, ob, upangledeg, sideangledeg, radius, offset);
}
@@ -1471,18 +1489,21 @@ static void correct_uv_aspect(Object *ob, BMEditMesh *em)
/** \name UV Map Clip & Correct
* \{ */
-static void uv_map_clip_correct_properties(wmOperatorType *ot)
+static void uv_map_clip_correct_properties_ex(wmOperatorType *ot, bool clip_to_bounds)
{
RNA_def_boolean(ot->srna,
"correct_aspect",
1,
"Correct Aspect",
"Map UVs taking image aspect ratio into account");
- RNA_def_boolean(ot->srna,
- "clip_to_bounds",
- 0,
- "Clip to Bounds",
- "Clip UV coordinates to bounds after unwrapping");
+ /* Optional, since not all unwrapping types need to be clipped. */
+ if (clip_to_bounds) {
+ RNA_def_boolean(ot->srna,
+ "clip_to_bounds",
+ 0,
+ "Clip to Bounds",
+ "Clip UV coordinates to bounds after unwrapping");
+ }
RNA_def_boolean(ot->srna,
"scale_to_bounds",
0,
@@ -1490,6 +1511,11 @@ static void uv_map_clip_correct_properties(wmOperatorType *ot)
"Scale UV coordinates to bounds after unwrapping");
}
+static void uv_map_clip_correct_properties(wmOperatorType *ot)
+{
+ uv_map_clip_correct_properties_ex(ot, true);
+}
+
static void uv_map_clip_correct_multi(Object **objects, uint objects_len, wmOperator *op)
{
BMFace *efa;
@@ -1498,7 +1524,8 @@ static void uv_map_clip_correct_multi(Object **objects, uint objects_len, wmOper
MLoopUV *luv;
float dx, dy, min[2], max[2];
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
- const bool clip_to_bounds = RNA_boolean_get(op->ptr, "clip_to_bounds");
+ const bool clip_to_bounds = (RNA_struct_find_property(op->ptr, "clip_to_bounds") &&
+ RNA_boolean_get(op->ptr, "clip_to_bounds"));
const bool scale_to_bounds = RNA_boolean_get(op->ptr, "scale_to_bounds");
INIT_MINMAX2(min, max);
@@ -1635,7 +1662,8 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len
if (scene->toolsettings->edge_mode_live_unwrap) {
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = false,
+ .only_selected_faces = false,
+ .only_selected_uvs = true,
.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0,
.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0,
};
@@ -1670,7 +1698,8 @@ static int unwrap_exec(bContext *C, wmOperator *op)
const UnwrapOptions options = {
.topology_from_uvs = false,
- .only_selected = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = true,
.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"),
.correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"),
};
@@ -1829,6 +1858,363 @@ void UV_OT_unwrap(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Smart UV Project Operator
+ * \{ */
+
+/* Ignore all areas below this, as the UV's get zeroed. */
+static const float smart_uv_project_area_ignore = 1e-12f;
+
+typedef struct ThickFace {
+ float area;
+ BMFace *efa;
+} ThickFace;
+
+static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p)
+{
+
+ const ThickFace *tf_a = (ThickFace *)tf_a_p;
+ const ThickFace *tf_b = (ThickFace *)tf_b_p;
+
+ /* Ignore the area of small faces.
+ * Also, order checks so `!isfinite(...)` values are counted as zero area. */
+ if (!((tf_a->area > smart_uv_project_area_ignore) ||
+ (tf_b->area > smart_uv_project_area_ignore))) {
+ return 0;
+ }
+
+ if (tf_a->area < tf_b->area) {
+ return 1;
+ }
+ if (tf_a->area > tf_b->area) {
+ return -1;
+ }
+ return 0;
+}
+
+static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_faces,
+ const uint thick_faces_len,
+ BMesh *bm,
+ const float project_angle_limit_half_cos,
+ const float project_angle_limit_cos,
+ const float area_weight,
+ float (**r_project_normal_array)[3])
+{
+ if (UNLIKELY(thick_faces_len == 0)) {
+ *r_project_normal_array = NULL;
+ return 0;
+ }
+
+ const float *project_normal = thick_faces[0].efa->no;
+
+ const ThickFace **project_thick_faces = NULL;
+ BLI_array_declare(project_thick_faces);
+
+ float(*project_normal_array)[3] = NULL;
+ BLI_array_declare(project_normal_array);
+
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ while (true) {
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ if (dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) {
+ BLI_array_append(project_thick_faces, &thick_faces[f_index]);
+ BM_elem_flag_set(thick_faces[f_index].efa, BM_ELEM_TAG, true);
+ }
+ }
+
+ float average_normal[3] = {0.0f, 0.0f, 0.0f};
+
+ if (area_weight <= 0.0f) {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ add_v3_v3(average_normal, tf->efa->no);
+ }
+ }
+ else if (area_weight >= 1.0f) {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ madd_v3_v3fl(average_normal, tf->efa->no, tf->area);
+ }
+ }
+ else {
+ for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces);
+ f_proj_index++) {
+ const ThickFace *tf = project_thick_faces[f_proj_index];
+ const float area_blend = (tf->area * area_weight) + (1.0f - area_weight);
+ madd_v3_v3fl(average_normal, tf->efa->no, area_blend);
+ }
+ }
+
+ /* Avoid NAN. */
+ if (normalize_v3(average_normal) != 0.0f) {
+ float(*normal)[3] = BLI_array_append_ret(project_normal_array);
+ copy_v3_v3(*normal, average_normal);
+ }
+
+ /* Find the most unique angle that points away from other normals. */
+ float anble_best = 1.0f;
+ uint angle_best_index = 0;
+
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ if (BM_elem_flag_test(thick_faces[f_index].efa, BM_ELEM_TAG)) {
+ continue;
+ }
+
+ float angle_test = -1.0f;
+ for (int p_index = 0; p_index < BLI_array_len(project_normal_array); p_index++) {
+ angle_test = max_ff(angle_test,
+ dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no));
+ }
+
+ if (angle_test < anble_best) {
+ anble_best = angle_test;
+ angle_best_index = f_index;
+ }
+ }
+
+ if (anble_best < project_angle_limit_cos) {
+ project_normal = thick_faces[angle_best_index].efa->no;
+ BLI_array_clear(project_thick_faces);
+ BLI_array_append(project_thick_faces, &thick_faces[angle_best_index]);
+ BM_elem_flag_enable(thick_faces[angle_best_index].efa, BM_ELEM_TAG);
+ }
+ else {
+ if (BLI_array_len(project_normal_array) >= 1) {
+ break;
+ }
+ }
+ }
+
+ BLI_array_free(project_thick_faces);
+ BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+ *r_project_normal_array = project_normal_array;
+ return BLI_array_len(project_normal_array);
+}
+
+static int smart_project_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+
+ /* May be NULL. */
+ View3D *v3d = CTX_wm_view3d(C);
+
+ const float project_angle_limit = RNA_float_get(op->ptr, "angle_limit");
+ const float island_margin = RNA_float_get(op->ptr, "island_margin");
+ const float area_weight = RNA_float_get(op->ptr, "area_weight");
+
+ const float project_angle_limit_cos = cosf(project_angle_limit);
+ const float project_angle_limit_half_cos = cosf(project_angle_limit / 2);
+
+ /* Memory arena for list links (cleared for each object). */
+ MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ uint objects_len = 0;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
+ view_layer, v3d, &objects_len);
+
+ Object **objects_changed = MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__);
+ uint object_changed_len = 0;
+
+ BMFace *efa;
+ BMIter iter;
+ uint ob_index;
+
+ for (ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ bool changed = false;
+
+ const uint cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__);
+
+ uint thick_faces_len = 0;
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
+ continue;
+ }
+ thick_faces[thick_faces_len].area = BM_face_calc_area(efa);
+ thick_faces[thick_faces_len].efa = efa;
+ thick_faces_len++;
+ }
+
+ qsort(thick_faces, thick_faces_len, sizeof(ThickFace), smart_uv_project_thickface_area_cmp_fn);
+
+ /* Remove all zero area faces. */
+ while ((thick_faces_len > 0) &&
+ !(thick_faces[thick_faces_len - 1].area > smart_uv_project_area_ignore)) {
+
+ /* Zero UV's so they don't overlap with other faces being unwrapped. */
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ zero_v2(luv->uv);
+ changed = true;
+ }
+
+ thick_faces_len -= 1;
+ }
+
+ float(*project_normal_array)[3] = NULL;
+ int project_normals_len = smart_uv_project_calculate_project_normals(
+ thick_faces,
+ thick_faces_len,
+ em->bm,
+ project_angle_limit_half_cos,
+ project_angle_limit_cos,
+ area_weight,
+ &project_normal_array);
+
+ if (project_normals_len == 0) {
+ MEM_freeN(thick_faces);
+ BLI_assert(project_normal_array == NULL);
+ continue;
+ }
+
+ /* After finding projection vectors, we find the uv positions. */
+ LinkNode **thickface_project_groups = MEM_callocN(
+ sizeof(*thickface_project_groups) * project_normals_len, __func__);
+
+ BLI_memarena_clear(arena);
+
+ for (int f_index = thick_faces_len - 1; f_index >= 0; f_index--) {
+ const float *f_normal = thick_faces[f_index].efa->no;
+
+ float angle_best = dot_v3v3(f_normal, project_normal_array[0]);
+ uint angle_best_index = 0;
+
+ for (int p_index = 1; p_index < project_normals_len; p_index++) {
+ const float angle_test = dot_v3v3(f_normal, project_normal_array[p_index]);
+ if (angle_test > angle_best) {
+ angle_best = angle_test;
+ angle_best_index = p_index;
+ }
+ }
+
+ BLI_linklist_prepend_arena(
+ &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena);
+ }
+
+ for (int p_index = 0; p_index < project_normals_len; p_index++) {
+ if (thickface_project_groups[p_index] == NULL) {
+ continue;
+ }
+
+ float axis_mat[3][3];
+ axis_dominant_v3_to_m3_negate(axis_mat, project_normal_array[p_index]);
+
+ for (LinkNode *list = thickface_project_groups[p_index]; list; list = list->next) {
+ ThickFace *tf = list->link;
+ BMIter liter;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ mul_v2_m3v3(luv->uv, axis_mat, l->v->co);
+ }
+ changed = true;
+ }
+ }
+
+ MEM_freeN(thick_faces);
+ MEM_freeN(project_normal_array);
+
+ /* No need to free the lists in 'thickface_project_groups' values as the 'arena' is used. */
+ MEM_freeN(thickface_project_groups);
+
+ if (changed) {
+ objects_changed[object_changed_len] = objects[ob_index];
+ object_changed_len += 1;
+ }
+ }
+
+ BLI_memarena_free(arena);
+
+ MEM_freeN(objects);
+
+ /* Pack islands & Stretch to UV bounds */
+ if (object_changed_len > 0) {
+
+ scene->toolsettings->uvcalc_margin = island_margin;
+ const UnwrapOptions options = {
+ .topology_from_uvs = true,
+ .only_selected_faces = true,
+ .only_selected_uvs = false,
+ .fill_holes = true,
+ .correct_aspect = false,
+ };
+
+ /* Depsgraph refresh functions are called here. */
+ uvedit_pack_islands_multi(scene, objects_changed, object_changed_len, &options, true, false);
+ uv_map_clip_correct_multi(objects_changed, object_changed_len, op);
+ }
+
+ MEM_freeN(objects_changed);
+
+ return OPERATOR_FINISHED;
+}
+
+void UV_OT_smart_project(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Smart UV Project";
+ ot->idname = "UV_OT_smart_project";
+ ot->description = "Projection unwraps the selected faces of mesh objects";
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* api callbacks */
+ ot->exec = smart_project_exec;
+ ot->poll = ED_operator_uvmap;
+ ot->invoke = WM_operator_props_popup_confirm;
+
+ /* properties */
+ prop = RNA_def_float_rotation(ot->srna,
+ "angle_limit",
+ 0,
+ NULL,
+ DEG2RADF(0.0f),
+ DEG2RADF(90.0f),
+ "Angle Limit",
+ "Lower for more projection groups, higher for less distortion",
+ DEG2RADF(0.0f),
+ DEG2RADF(89.0f));
+ RNA_def_property_float_default(prop, DEG2RADF(66.0f));
+
+ RNA_def_float(ot->srna,
+ "island_margin",
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ "Island Margin",
+ "Margin to reduce bleed from adjacent islands",
+ 0.0f,
+ 1.0f);
+ RNA_def_float(ot->srna,
+ "area_weight",
+ 0.0f,
+ 0.0f,
+ 1.0f,
+ "Area Weight",
+ "Weight projections vector by faces with larger areas",
+ 0.0f,
+ 1.0f);
+
+ uv_map_clip_correct_properties_ex(ot, false);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Project UV From View Operator
* \{ */
diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h
index 57b6dc815a3..bc5e9d49bee 100644
--- a/source/blender/freestyle/FRS_freestyle.h
+++ b/source/blender/freestyle/FRS_freestyle.h
@@ -42,7 +42,7 @@ struct FreestyleGlobals {
extern struct FreestyleGlobals g_freestyle;
/* Rendering */
-void FRS_initialize(void);
+void FRS_init(void);
void FRS_set_context(struct bContext *C);
int FRS_is_freestyle_enabled(struct ViewLayer *view_layer);
void FRS_init_stroke_renderer(struct Render *re);
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index f9edadb2d4a..dea09b7620f 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -316,10 +316,9 @@ int Controller::LoadMesh(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph
ClearRootNode();
return 0;
}
- else {
- delete _ViewMap;
- _ViewMap = NULL;
- }
+
+ delete _ViewMap;
+ _ViewMap = NULL;
}
_Chrono.start();
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index e1763514e08..a06218620ac 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -684,7 +684,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
if (v0 == v1 || v0 == v2 || v1 == v2) {
continue; // do nothing for now
}
- else if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) {
+ if (GeomUtils::distPointSegment<Vec3r>(v0, v1, v2) < 1.0e-6) {
detri.viP = vi0;
detri.viA = vi1;
detri.viB = vi2;
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 51ac281e330..2b43e913b3d 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -100,7 +100,7 @@ static bCallbackFuncStore load_post_callback_funcstore = {
// Initialization
//=======================================================
-void FRS_initialize()
+void FRS_init()
{
if (freestyle_is_initialized) {
return;
diff --git a/source/blender/freestyle/intern/geometry/GeomUtils.cpp b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
index 4c4f12faaba..dbd792852ad 100644
--- a/source/blender/freestyle/intern/geometry/GeomUtils.cpp
+++ b/source/blender/freestyle/intern/geometry/GeomUtils.cpp
@@ -514,9 +514,8 @@ intersection_test intersectRayPlane(const Vec3r &orig,
if (fabs((norm * orig) + d) <= epsilon) {
return COINCIDENT; // plane and ray are coincident
}
- else {
- return COLINEAR;
- }
+
+ return COLINEAR;
}
t = -(d + (norm * orig)) / denom;
@@ -766,9 +765,8 @@ inline bool intersect2dSegPoly(Vec2r *seg, Vec2r *poly, unsigned n)
if (N < 0) {
return false;
}
- else {
- continue;
- }
+
+ continue;
}
t = N / D;
diff --git a/source/blender/freestyle/intern/python/BPy_Convert.cpp b/source/blender/freestyle/intern/python/BPy_Convert.cpp
index 427e4198e5c..03f9760344b 100644
--- a/source/blender/freestyle/intern/python/BPy_Convert.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Convert.cpp
@@ -110,22 +110,22 @@ PyObject *Any_BPy_Interface0D_from_Interface0D(Interface0D &if0D)
if (typeid(if0D) == typeid(CurvePoint)) {
return BPy_CurvePoint_from_CurvePoint(dynamic_cast<CurvePoint &>(if0D));
}
- else if (typeid(if0D) == typeid(StrokeVertex)) {
+ if (typeid(if0D) == typeid(StrokeVertex)) {
return BPy_StrokeVertex_from_StrokeVertex(dynamic_cast<StrokeVertex &>(if0D));
}
- else if (typeid(if0D) == typeid(SVertex)) {
+ if (typeid(if0D) == typeid(SVertex)) {
return BPy_SVertex_from_SVertex(dynamic_cast<SVertex &>(if0D));
}
- else if (typeid(if0D) == typeid(ViewVertex)) {
+ if (typeid(if0D) == typeid(ViewVertex)) {
return BPy_ViewVertex_from_ViewVertex(dynamic_cast<ViewVertex &>(if0D));
}
- else if (typeid(if0D) == typeid(NonTVertex)) {
+ if (typeid(if0D) == typeid(NonTVertex)) {
return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(if0D));
}
- else if (typeid(if0D) == typeid(TVertex)) {
+ if (typeid(if0D) == typeid(TVertex)) {
return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(if0D));
}
- else if (typeid(if0D) == typeid(Interface0D)) {
+ if (typeid(if0D) == typeid(Interface0D)) {
return BPy_Interface0D_from_Interface0D(if0D);
}
string msg("unexpected type: " + if0D.getExactTypeName());
@@ -138,22 +138,22 @@ PyObject *Any_BPy_Interface1D_from_Interface1D(Interface1D &if1D)
if (typeid(if1D) == typeid(ViewEdge)) {
return BPy_ViewEdge_from_ViewEdge(dynamic_cast<ViewEdge &>(if1D));
}
- else if (typeid(if1D) == typeid(Chain)) {
+ if (typeid(if1D) == typeid(Chain)) {
return BPy_Chain_from_Chain(dynamic_cast<Chain &>(if1D));
}
- else if (typeid(if1D) == typeid(Stroke)) {
+ if (typeid(if1D) == typeid(Stroke)) {
return BPy_Stroke_from_Stroke(dynamic_cast<Stroke &>(if1D));
}
- else if (typeid(if1D) == typeid(FEdgeSharp)) {
+ if (typeid(if1D) == typeid(FEdgeSharp)) {
return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(if1D));
}
- else if (typeid(if1D) == typeid(FEdgeSmooth)) {
+ if (typeid(if1D) == typeid(FEdgeSmooth)) {
return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(if1D));
}
- else if (typeid(if1D) == typeid(FEdge)) {
+ if (typeid(if1D) == typeid(FEdge)) {
return BPy_FEdge_from_FEdge(dynamic_cast<FEdge &>(if1D));
}
- else if (typeid(if1D) == typeid(Interface1D)) {
+ if (typeid(if1D) == typeid(Interface1D)) {
return BPy_Interface1D_from_Interface1D(if1D);
}
string msg("unexpected type: " + if1D.getExactTypeName());
@@ -166,10 +166,10 @@ PyObject *Any_BPy_FEdge_from_FEdge(FEdge &fe)
if (typeid(fe) == typeid(FEdgeSharp)) {
return BPy_FEdgeSharp_from_FEdgeSharp(dynamic_cast<FEdgeSharp &>(fe));
}
- else if (typeid(fe) == typeid(FEdgeSmooth)) {
+ if (typeid(fe) == typeid(FEdgeSmooth)) {
return BPy_FEdgeSmooth_from_FEdgeSmooth(dynamic_cast<FEdgeSmooth &>(fe));
}
- else if (typeid(fe) == typeid(FEdge)) {
+ if (typeid(fe) == typeid(FEdge)) {
return BPy_FEdge_from_FEdge(fe);
}
string msg("unexpected type: " + fe.getExactTypeName());
@@ -182,10 +182,10 @@ PyObject *Any_BPy_ViewVertex_from_ViewVertex(ViewVertex &vv)
if (typeid(vv) == typeid(NonTVertex)) {
return BPy_NonTVertex_from_NonTVertex(dynamic_cast<NonTVertex &>(vv));
}
- else if (typeid(vv) == typeid(TVertex)) {
+ if (typeid(vv) == typeid(TVertex)) {
return BPy_TVertex_from_TVertex(dynamic_cast<TVertex &>(vv));
}
- else if (typeid(vv) == typeid(ViewVertex)) {
+ if (typeid(vv) == typeid(ViewVertex)) {
return BPy_ViewVertex_from_ViewVertex(vv);
}
string msg("unexpected type: " + vv.getExactTypeName());
@@ -773,7 +773,7 @@ bool float_array_from_PyObject(PyObject *obj, float *v, int n)
}
return 1;
}
- else if (ColorObject_Check(obj) && n == 3) {
+ if (ColorObject_Check(obj) && n == 3) {
if (BaseMath_ReadCallback((BaseMathObject *)obj) == -1) {
return 0;
}
@@ -782,10 +782,10 @@ bool float_array_from_PyObject(PyObject *obj, float *v, int n)
}
return 1;
}
- else if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) {
+ if (PyList_Check(obj) && PyList_GET_SIZE(obj) == n) {
return float_array_from_PyList(obj, v, n);
}
- else if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) {
+ if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == n) {
return float_array_from_PyTuple(obj, v, n);
}
return 0;
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 33078e6ba6a..9796dcda964 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -264,7 +264,7 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
return NULL;
}
cumap = (CurveMapping *)py_srna->ptr.data;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
/* disable extrapolation if enabled */
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE)) {
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
index 2c226e330d7..dbf1c12fb01 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
@@ -108,7 +108,7 @@ static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwd
self->m = new FrsMaterial(*m);
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O&O&O&O&O&fi",
@@ -508,9 +508,8 @@ static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
if (comparison_type == Py_NE) {
Py_RETURN_TRUE;
}
- else {
- Py_RETURN_FALSE;
- }
+
+ Py_RETURN_FALSE;
}
matA = (BPy_FrsMaterial *)objectA;
@@ -531,9 +530,8 @@ static PyObject *BPy_FrsMaterial_richcmpr(PyObject *objectA,
if (result == true) {
Py_RETURN_TRUE;
}
- else {
- Py_RETURN_FALSE;
- }
+
+ Py_RETURN_FALSE;
}
static Py_hash_t FrsMaterial_hash(PyObject *self)
diff --git a/source/blender/freestyle/intern/python/BPy_Id.cpp b/source/blender/freestyle/intern/python/BPy_Id.cpp
index 4f61ba847f6..eb0eb661e3d 100644
--- a/source/blender/freestyle/intern/python/BPy_Id.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Id.cpp
@@ -75,7 +75,7 @@ static int Id_init(BPy_Id *self, PyObject *args, PyObject *kwds)
if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_1, &Id_Type, &brother)) {
self->id = new Id(*(((BPy_Id *)brother)->id));
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "|ii", (char **)kwlist_2, &first, &second)) {
self->id = new Id(first, second);
}
diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
index 98b0099bcad..9c155db913c 100644
--- a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
+++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp
@@ -88,21 +88,20 @@ static PyObject *Integrator_integrate(PyObject * /*self*/, PyObject *args, PyObj
double res = integrate(*fun, it, it_end, t);
return PyFloat_FromDouble(res);
}
- else if (BPy_UnaryFunction0DFloat_Check(obj1)) {
+ if (BPy_UnaryFunction0DFloat_Check(obj1)) {
UnaryFunction0D<float> *fun = ((BPy_UnaryFunction0DFloat *)obj1)->uf0D_float;
float res = integrate(*fun, it, it_end, t);
return PyFloat_FromDouble(res);
}
- else if (BPy_UnaryFunction0DUnsigned_Check(obj1)) {
+ if (BPy_UnaryFunction0DUnsigned_Check(obj1)) {
UnaryFunction0D<unsigned int> *fun = ((BPy_UnaryFunction0DUnsigned *)obj1)->uf0D_unsigned;
unsigned int res = integrate(*fun, it, it_end, t);
return PyLong_FromLong(res);
}
- else {
- string class_name(Py_TYPE(obj1)->tp_name);
- PyErr_SetString(PyExc_TypeError, ("unsupported function type: " + class_name).c_str());
- return NULL;
- }
+
+ string class_name(Py_TYPE(obj1)->tp_name);
+ PyErr_SetString(PyExc_TypeError, ("unsupported function type: " + class_name).c_str());
+ return NULL;
}
/*-----------------------Integrator module docstring---------------------------------------*/
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index 510e823ba55..56f95b8ecbb 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -365,8 +365,8 @@ static PyObject *Operators_sequential_split(BPy_Operators * /*self*/,
return NULL;
}
}
- else if (PyErr_Clear(),
- (f = 0.0f),
+ else if ((void)PyErr_Clear(),
+ (void)(f = 0.0f),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!|f", (char **)kwlist_2, &UnaryPredicate0D_Type, &obj1, &f)) {
if (!((BPy_UnaryPredicate0D *)obj1)->up0D) {
@@ -484,8 +484,8 @@ static PyObject *Operators_recursive_split(BPy_Operators * /*self*/,
return NULL;
}
}
- else if (PyErr_Clear(),
- (f = 0.0f),
+ else if ((void)PyErr_Clear(),
+ (void)(f = 0.0f),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!O!|f",
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
index 5f5407e82e3..214385f74ad 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
@@ -110,7 +110,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj
self->sa = new StrokeAttribute(*(((BPy_StrokeAttribute *)obj1)->sa));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -123,7 +123,7 @@ static int StrokeAttribute_init(BPy_StrokeAttribute *self, PyObject *args, PyObj
self->sa = new StrokeAttribute(
*(((BPy_StrokeAttribute *)obj1)->sa), *(((BPy_StrokeAttribute *)obj2)->sa), t);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"ffffff",
diff --git a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
index f59ae15ae01..2adcae13e6d 100644
--- a/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
+++ b/source/blender/freestyle/intern/python/BPy_ViewShape.cpp
@@ -88,7 +88,7 @@ static int ViewShape_init(BPy_ViewShape *self, PyObject *args, PyObject *kwds)
self->py_ss = ((BPy_ViewShape *)obj)->py_ss;
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &SShape_Type, &obj)) {
BPy_SShape *py_ss = (BPy_SShape *)obj;
self->vs = new ViewShape(py_ss->ss);
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
index 6af80c4bfd9..81dd79ff270 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_CurvePoint.cpp
@@ -95,7 +95,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
self->cp = new CurvePoint(*(((BPy_CurvePoint *)obj1)->cp));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -107,7 +107,7 @@ static int CurvePoint_init(BPy_CurvePoint *self, PyObject *args, PyObject *kwds)
&t2d)) {
self->cp = new CurvePoint(((BPy_SVertex *)obj1)->sv, ((BPy_SVertex *)obj2)->sv, t2d);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
diff --git a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
index 71a87c2c01e..c01f1f17000 100644
--- a/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/BPy_SVertex.cpp
@@ -72,7 +72,7 @@ static int SVertex_init(BPy_SVertex *self, PyObject *args, PyObject *kwds)
self->sv = new SVertex(*(((BPy_SVertex *)obj)->sv));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O&O!", (char **)kwlist_2, convert_v3, v, &Id_Type, &obj)) {
Vec3r point_3d(v[0], v[1], v[2]);
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
index b4c08714af0..519bd72db3b 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
@@ -107,7 +107,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
self->sv = new StrokeVertex(*(((BPy_StrokeVertex *)obj1)->sv));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!f",
@@ -129,7 +129,7 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
}
self->sv = new StrokeVertex(sv1, sv2, t3d);
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_3, &CurvePoint_Type, &obj1)) {
CurvePoint *cp = ((BPy_CurvePoint *)obj1)->cp;
@@ -139,8 +139,8 @@ static int StrokeVertex_init(BPy_StrokeVertex *self, PyObject *args, PyObject *k
}
self->sv = new StrokeVertex(cp);
}
- else if (PyErr_Clear(),
- (obj2 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj2 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!|O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
index 8a09e7722ea..187ab94360a 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp
@@ -81,7 +81,7 @@ static int FEdge_init(BPy_FEdge *self, PyObject *args, PyObject *kwds)
self->fe = new FEdge(*(((BPy_FEdge *)obj1)->fe));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
index fd434f9c4ef..788dfa78992 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FrsCurve.cpp
@@ -72,7 +72,7 @@ static int FrsCurve_init(BPy_FrsCurve *self, PyObject *args, PyObject *kwds)
self->c = new Curve(*(((BPy_FrsCurve *)obj)->c));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) {
self->c = new Curve(*(((BPy_Id *)obj)->id));
}
diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
index 3a25ddb0252..b31efe1f923 100644
--- a/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/BPy_Stroke.cpp
@@ -157,7 +157,8 @@ static PyObject *Stroke_resample(BPy_Stroke *self, PyObject *args, PyObject *kwd
return NULL;
}
}
- else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) {
+ else if ((void)PyErr_Clear(),
+ PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &f)) {
if (self->s->Resample(f) < 0) {
PyErr_SetString(PyExc_RuntimeError, "Stroke resampling (by vertex interval) failed");
return NULL;
diff --git a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
index 285100193d3..9cdc344081e 100644
--- a/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/Curve/BPy_Chain.cpp
@@ -71,7 +71,7 @@ static int Chain_init(BPy_Chain *self, PyObject *args, PyObject *kwds)
self->c = new Chain(*(((BPy_Chain *)obj)->c));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args, kwds, "O!", (char **)kwlist_2, &Id_Type, &obj)) {
self->c = new Chain(*(((BPy_Id *)obj)->id));
}
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
index 725daa80b5e..5db75c84608 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSharp.cpp
@@ -75,7 +75,7 @@ static int FEdgeSharp_init(BPy_FEdgeSharp *self, PyObject *args, PyObject *kwds)
self->fes = new FEdgeSharp(*(((BPy_FEdgeSharp *)obj1)->fes));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
index 65d9dcbe01f..3fb739b18db 100644
--- a/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
+++ b/source/blender/freestyle/intern/python/Interface1D/FEdge/BPy_FEdgeSmooth.cpp
@@ -73,7 +73,7 @@ static int FEdgeSmooth_init(BPy_FEdgeSmooth *self, PyObject *args, PyObject *kwd
self->fes = new FEdgeSmooth(*(((BPy_FEdgeSmooth *)obj1)->fes));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
index 74ae7809284..90e751333b9 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_AdjacencyIterator.cpp
@@ -82,8 +82,8 @@ static int AdjacencyIterator_init(BPy_AdjacencyIterator *self, PyObject *args, P
self->at_start = ((BPy_AdjacencyIterator *)obj1)->at_start;
}
}
- else if (PyErr_Clear(),
- (obj2 = obj3 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj2 = obj3 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!|O!O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index 164e1646934..1703fc2bddb 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -114,8 +114,8 @@ static int ChainPredicateIterator_init(BPy_ChainPredicateIterator *self,
Py_INCREF(self->upred);
Py_INCREF(self->bpred);
}
- else if (PyErr_Clear(),
- (obj3 = obj4 = obj5 = obj6 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj3 = obj4 = obj5 = obj6 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!|O!O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
index 401959be0c0..d8ad82d667c 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
@@ -91,8 +91,8 @@ static int ChainSilhouetteIterator_init(BPy_ChainSilhouetteIterator *self,
args, kwds, "O!", (char **)kwlist_1, &ChainSilhouetteIterator_Type, &obj1)) {
self->cs_it = new ChainSilhouetteIterator(*(((BPy_ChainSilhouetteIterator *)obj1)->cs_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = obj3 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = obj3 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"|O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
index b6d841c5b64..dbd6e8dd09d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainingIterator.cpp
@@ -91,8 +91,8 @@ static int ChainingIterator___init__(BPy_ChainingIterator *self, PyObject *args,
args, kwds, "O!", (char **)kwlist_1, &ChainingIterator_Type, &obj1)) {
self->c_it = new ChainingIterator(*(((BPy_ChainingIterator *)obj1)->c_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = obj3 = obj4 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = obj3 = obj4 = 0),
PyArg_ParseTupleAndKeywords(args,
kwds,
"|O!O!O&O!",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
index 6ea61a060cb..6c496b0308b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_CurvePointIterator.cpp
@@ -75,7 +75,8 @@ static int CurvePointIterator_init(BPy_CurvePointIterator *self, PyObject *args,
*(((BPy_CurvePointIterator *)brother)->cp_it));
}
}
- else if (PyErr_Clear(), PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) {
+ else if ((void)PyErr_Clear(),
+ PyArg_ParseTupleAndKeywords(args, kwds, "f", (char **)kwlist_2, &step)) {
self->cp_it = new CurveInternal::CurvePointIterator(step);
}
else {
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
index 0dbef9f325c..734ed0117f4 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
@@ -81,14 +81,14 @@ static int Interface0DIterator_init(BPy_Interface0DIterator *self, PyObject *arg
self->at_start = true;
self->reversed = false;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_2, &Interface1D_Type, &inter)) {
self->if0D_it = new Interface0DIterator(((BPy_Interface1D *)inter)->if1D->verticesBegin());
self->at_start = true;
self->reversed = false;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "O!", (char **)kwlist_3, &Interface0DIterator_Type, &brother)) {
self->if0D_it = new Interface0DIterator(*(((BPy_Interface0DIterator *)brother)->if0D_it));
@@ -124,7 +124,7 @@ static PyObject *Interface0DIterator_iternext(BPy_Interface0DIterator *self)
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
- else if (self->at_start) {
+ if (self->at_start) {
self->at_start = false;
}
else if (self->if0D_it->atLast()) {
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
index dd738b97473..4a5927ff6eb 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_SVertexIterator.cpp
@@ -82,7 +82,7 @@ static int SVertexIterator_init(BPy_SVertexIterator *self, PyObject *args, PyObj
self->sv_it = new ViewEdgeInternal::SVertexIterator(*(((BPy_SVertexIterator *)obj1)->sv_it));
}
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(args,
kwds,
"O!O!O!O!f",
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
index 84f57f1fe31..cda4031240b 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_StrokeVertexIterator.cpp
@@ -74,7 +74,7 @@ static int StrokeVertexIterator_init(BPy_StrokeVertexIterator *self,
self->at_start = ((BPy_StrokeVertexIterator *)brother)->at_start;
}
- else if (PyErr_Clear(),
+ else if ((void)PyErr_Clear(),
PyArg_ParseTupleAndKeywords(
args, kwds, "|O!", (char **)kwlist_2, &Stroke_Type, &stroke)) {
if (!stroke) {
@@ -125,7 +125,7 @@ static PyObject *StrokeVertexIterator_iternext(BPy_StrokeVertexIterator *self)
}
/* If at the start of the iterator, only return the object
* and don't increment, to keep for-loops in sync */
- else if (self->at_start) {
+ if (self->at_start) {
self->at_start = false;
}
/* If sv_it.atLast() is true, the iterator is currently pointing to the final valid element.
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
index c8a978784a4..3d0ed5d5a4d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ViewEdgeIterator.cpp
@@ -78,8 +78,8 @@ static int ViewEdgeIterator_init(BPy_ViewEdgeIterator *self, PyObject *args, PyO
args, kwds, "O!", (char **)kwlist_1, &ViewEdgeIterator_Type, &obj1)) {
self->ve_it = new ViewEdgeInternal::ViewEdgeIterator(*(((BPy_ViewEdgeIterator *)obj1)->ve_it));
}
- else if (PyErr_Clear(),
- (obj1 = obj2 = 0),
+ else if ((void)PyErr_Clear(),
+ (void)(obj1 = obj2 = 0),
PyArg_ParseTupleAndKeywords(
args, kwds, "|O&O!", (char **)kwlist_2, check_begin, &obj1, &PyBool_Type, &obj2)) {
ViewEdge *begin = (!obj1 || obj1 == Py_None) ? NULL : ((BPy_ViewEdge *)obj1)->ve;
diff --git a/source/blender/freestyle/intern/stroke/Curve.cpp b/source/blender/freestyle/intern/stroke/Curve.cpp
index 02a1d32953d..51c40c890a3 100644
--- a/source/blender/freestyle/intern/stroke/Curve.cpp
+++ b/source/blender/freestyle/intern/stroke/Curve.cpp
@@ -216,10 +216,10 @@ FEdge *CurvePoint::getFEdge(Interface0D &inter)
if (iVertexB->__B == 0) {
return __A->getFEdge(*(iVertexB->__A));
}
- else if (iVertexB->__A == __A) {
+ if (iVertexB->__A == __A) {
return __A->getFEdge(*(iVertexB->__B));
}
- else if (iVertexB->__B == __A) {
+ if (iVertexB->__B == __A) {
return __A->getFEdge(*(iVertexB->__A));
}
}
@@ -227,7 +227,7 @@ FEdge *CurvePoint::getFEdge(Interface0D &inter)
if (iVertexB->__A == __A) {
return __B->getFEdge(*(iVertexB->__A));
}
- else if (iVertexB->__A == __B) {
+ if (iVertexB->__A == __B) {
return __A->getFEdge(*(iVertexB->__A));
}
}
diff --git a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
index a76579c7c96..a29d015b4c9 100644
--- a/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/stroke/StrokeRenderer.cpp
@@ -101,9 +101,8 @@ unsigned TextureManager::getBrushTextureIndex(string name, Stroke::MediumType lo
cerr << "brush file " << name << " not found" << endl;
return 0;
}
- else {
- return _brushesMap[bt];
- }
+
+ return _brushesMap[bt];
}
void TextureManager::Options::setPatternsPath(const string &path)
diff --git a/source/blender/freestyle/intern/system/PseudoNoise.cpp b/source/blender/freestyle/intern/system/PseudoNoise.cpp
index 048be5d018c..c05c269c404 100644
--- a/source/blender/freestyle/intern/system/PseudoNoise.cpp
+++ b/source/blender/freestyle/intern/system/PseudoNoise.cpp
@@ -33,9 +33,8 @@ static int modf_to_index(Freestyle::real x, unsigned int range)
BLI_assert(i >= 0 && i < range);
return i;
}
- else {
- return 0;
- }
+
+ return 0;
}
namespace Freestyle {
diff --git a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
index 55bc02b8358..26a40ee587c 100644
--- a/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
+++ b/source/blender/freestyle/intern/view_map/HeuristicGridDensityProviderFactory.cpp
@@ -43,9 +43,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity
if (avg->cellSize() > p23->cellSize()) {
return (AutoPtr<GridDensityProvider>)p23;
}
- else {
- return (AutoPtr<GridDensityProvider>)avg;
- }
+
+ return (AutoPtr<GridDensityProvider>)avg;
}
AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(
@@ -58,9 +57,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity
if (avg->cellSize() > p23->cellSize()) {
return (AutoPtr<GridDensityProvider>)p23;
}
- else {
- return (AutoPtr<GridDensityProvider>)avg;
- }
+
+ return (AutoPtr<GridDensityProvider>)avg;
}
AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensityProvider(
@@ -75,9 +73,8 @@ AutoPtr<GridDensityProvider> HeuristicGridDensityProviderFactory::newGridDensity
if (avg->cellSize() > p23->cellSize()) {
return (AutoPtr<GridDensityProvider>)p23;
}
- else {
- return (AutoPtr<GridDensityProvider>)avg;
- }
+
+ return (AutoPtr<GridDensityProvider>)avg;
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/view_map/OccluderSource.cpp b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
index 7132e0172ae..e75856edc35 100644
--- a/source/blender/freestyle/intern/view_map/OccluderSource.cpp
+++ b/source/blender/freestyle/intern/view_map/OccluderSource.cpp
@@ -77,11 +77,10 @@ bool OccluderSource::next()
valid = false;
return false;
}
- else {
- vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
- currentFace = wFaces.begin();
- facesEnd = wFaces.end();
- }
+
+ vector<WFace *> &wFaces = (*currentShape)->GetFaceList();
+ currentFace = wFaces.begin();
+ facesEnd = wFaces.end();
}
buildCachedPolygon();
return true;
diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
index d024c360e3f..aecd37fa0de 100644
--- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp
@@ -344,9 +344,8 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer)
if (woeend == winner->getSmoothEdge()->woea()->twin()) {
return OWXFaceLayer(winner, true);
}
- else {
- return OWXFaceLayer(winner, false);
- }
+
+ return OWXFaceLayer(winner, false);
}
}
++f;
@@ -368,19 +367,17 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer)
if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(NULL, true);
}
- else {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
- return OWXFaceLayer(NULL, true);
- }
- if (woeend == winner->getSmoothEdge()->woea()->twin()) {
- return OWXFaceLayer(winner, true);
- }
- else {
- return OWXFaceLayer(winner, false);
- }
+
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
+ return OWXFaceLayer(NULL, true);
+ }
+ if (woeend == winner->getSmoothEdge()->woea()->twin()) {
+ return OWXFaceLayer(winner, true);
}
+
+ return OWXFaceLayer(winner, false);
}
return OWXFaceLayer(NULL, true);
}
@@ -429,9 +426,8 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa
if (woebegin == winner->getSmoothEdge()->woeb()->twin()) {
return OWXFaceLayer(winner, true);
}
- else {
- return OWXFaceLayer(winner, false);
- }
+
+ return OWXFaceLayer(winner, false);
}
}
}
@@ -452,19 +448,17 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa
if ((sameNatureLayers.empty()) || (sameNatureLayers.size() != 1)) {
return OWXFaceLayer(NULL, true);
}
- else {
- WXFaceLayer *winner = sameNatureLayers[0];
- // check face mark continuity
- if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
- return OWXFaceLayer(NULL, true);
- }
- if (woebegin == winner->getSmoothEdge()->woeb()->twin()) {
- return OWXFaceLayer(winner, true);
- }
- else {
- return OWXFaceLayer(winner, false);
- }
+
+ WXFaceLayer *winner = sameNatureLayers[0];
+ // check face mark continuity
+ if (winner->getFace()->GetMark() != iFaceLayer.fl->getFace()->GetMark()) {
+ return OWXFaceLayer(NULL, true);
+ }
+ if (woebegin == winner->getSmoothEdge()->woeb()->twin()) {
+ return OWXFaceLayer(winner, true);
}
+
+ return OWXFaceLayer(winner, false);
}
return OWXFaceLayer(NULL, true);
}
@@ -631,11 +625,10 @@ OWXEdge ViewEdgeXBuilder::FindNextWEdge(const OWXEdge &iEdge)
// So the vertex order is OK.
return OWXEdge(wxe, true);
}
- else {
- // That means that the face necessarily lies on the edge left.
- // So the vertex order is OK.
- return OWXEdge(wxe, false);
- }
+
+ // That means that the face necessarily lies on the edge left.
+ // So the vertex order is OK.
+ return OWXEdge(wxe, false);
}
// we did not find:
return OWXEdge(NULL, true);
@@ -679,9 +672,8 @@ OWXEdge ViewEdgeXBuilder::FindPreviousWEdge(const OWXEdge &iEdge)
if (wxe->GetbVertex() == v) {
return OWXEdge(wxe, true);
}
- else {
- return OWXEdge(wxe, false);
- }
+
+ return OWXEdge(wxe, false);
}
// we did not find:
return OWXEdge(NULL, true);
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index 47c6c3a1f6a..fa2f95dac72 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -323,18 +323,16 @@ static bool ViewEdgeComp(ViewVertex::directedViewEdge &dve1, ViewVertex::directe
if (v2.y() < 0) {
return true;
}
- else {
- return (v1.x() > v2.x());
- }
+
+ return (v1.x() > v2.x());
}
- else {
- if (v2.y() > 0) {
- return false;
- }
- else {
- return (v1.x() < v2.x());
- }
+
+ if (v2.y() > 0) {
+ return false;
}
+
+ return (v1.x() < v2.x());
+
return false;
}
diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
index 8ac272e92b5..a0989c52e4e 100644
--- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp
@@ -504,10 +504,10 @@ static void computeCumulativeVisibility(ViewMap *ioViewMap,
(*ve)->setaShape(0);
continue;
}
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
+
+ ++qiMajority;
+ qiMajority >>= 1;
+
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
cout << "\tqiMajority: " << qiMajority << endl;
@@ -702,10 +702,10 @@ static void computeDetailedVisibility(ViewMap *ioViewMap,
(*ve)->setaShape(0);
continue;
}
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
+
+ ++qiMajority;
+ qiMajority >>= 1;
+
#if LOGGING
if (_global.debug & G_DEBUG_FREESTYLE) {
cout << "\tqiMajority: " << qiMajority << endl;
@@ -873,10 +873,9 @@ static void computeFastVisibility(ViewMap *ioViewMap, G &grid, real epsilon)
(*ve)->setaShape(0);
continue;
}
- else {
- ++qiMajority;
- qiMajority >>= 1;
- }
+
+ ++qiMajority;
+ qiMajority >>= 1;
even_test = true;
maxIndex = 0;
diff --git a/source/blender/freestyle/intern/winged_edge/WEdge.cpp b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
index d624728250a..c8805c144e3 100644
--- a/source/blender/freestyle/intern/winged_edge/WEdge.cpp
+++ b/source/blender/freestyle/intern/winged_edge/WEdge.cpp
@@ -114,7 +114,7 @@ bool WVertex::isBoundary()
if (_Border == 1) {
return true;
}
- else if (_Border == 0) {
+ if (_Border == 0) {
return false;
}
@@ -412,9 +412,8 @@ bool WFace::getOppositeEdge(const WVertex *v, WOEdge *&e)
if (!e) {
return false;
}
- else {
- return true;
- }
+
+ return true;
}
float WFace::getArea()
diff --git a/source/blender/functions/CMakeLists.txt b/source/blender/functions/CMakeLists.txt
index 2686275e898..ad29dbe6668 100644
--- a/source/blender/functions/CMakeLists.txt
+++ b/source/blender/functions/CMakeLists.txt
@@ -57,3 +57,20 @@ set(LIB
)
blender_add_lib(bf_functions "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
+
+if(WITH_GTESTS)
+ set(TEST_SRC
+ tests/FN_array_spans_test.cc
+ tests/FN_attributes_ref_test.cc
+ tests/FN_cpp_type_test.cc
+ tests/FN_generic_vector_array_test.cc
+ tests/FN_multi_function_network_test.cc
+ tests/FN_multi_function_test.cc
+ tests/FN_spans_test.cc
+ )
+ set (TEST_LIB
+ bf_functions
+ )
+ include(GTestTesting)
+ blender_add_test_lib(bf_functions_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
+endif()
diff --git a/source/blender/functions/FN_array_spans.hh b/source/blender/functions/FN_array_spans.hh
index 52325c19c1b..976b9a44d3e 100644
--- a/source/blender/functions/FN_array_spans.hh
+++ b/source/blender/functions/FN_array_spans.hh
@@ -157,7 +157,7 @@ class GVArraySpan : public VArraySpanBase<void> {
this->type_ = &array.type();
this->virtual_size_ = virtual_size;
this->category_ = VArraySpanCategory::SingleArray;
- this->data_.single_array.start = array.buffer();
+ this->data_.single_array.start = array.data();
this->data_.single_array.size = array.size();
}
diff --git a/source/blender/functions/FN_attributes_ref.hh b/source/blender/functions/FN_attributes_ref.hh
index fe7e59b5e00..0cac8d82d26 100644
--- a/source/blender/functions/FN_attributes_ref.hh
+++ b/source/blender/functions/FN_attributes_ref.hh
@@ -49,12 +49,12 @@ class AttributesInfoBuilder : NonCopyable, NonMovable {
AttributesInfoBuilder() = default;
~AttributesInfoBuilder();
- template<typename T> void add(StringRef name, const T &default_value)
+ template<typename T> bool add(StringRef name, const T &default_value)
{
- this->add(name, CPPType::get<T>(), (const void *)&default_value);
+ return this->add(name, CPPType::get<T>(), (const void *)&default_value);
}
- void add(StringRef name, const CPPType &type, const void *default_value = nullptr);
+ bool add(StringRef name, const CPPType &type, const void *default_value = nullptr);
};
/**
diff --git a/source/blender/functions/FN_cpp_type.hh b/source/blender/functions/FN_cpp_type.hh
index 1176a705e66..2f1d3f83c63 100644
--- a/source/blender/functions/FN_cpp_type.hh
+++ b/source/blender/functions/FN_cpp_type.hh
@@ -370,7 +370,7 @@ class CPPType : NonCopyable, NonMovable {
void copy_to_initialized_n(const void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
+ BLI_assert(n == 0 || src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -379,7 +379,7 @@ class CPPType : NonCopyable, NonMovable {
void copy_to_initialized_indices(const void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
+ BLI_assert(mask.size() == 0 || src != dst);
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
@@ -405,7 +405,7 @@ class CPPType : NonCopyable, NonMovable {
void copy_to_uninitialized_n(const void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
+ BLI_assert(n == 0 || src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -414,7 +414,7 @@ class CPPType : NonCopyable, NonMovable {
void copy_to_uninitialized_indices(const void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
+ BLI_assert(mask.size() == 0 || src != dst);
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
@@ -440,7 +440,7 @@ class CPPType : NonCopyable, NonMovable {
void relocate_to_initialized_n(void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
+ BLI_assert(n == 0 || src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -449,7 +449,7 @@ class CPPType : NonCopyable, NonMovable {
void relocate_to_initialized_indices(void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
+ BLI_assert(mask.size() == 0 || src != dst);
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
@@ -475,7 +475,7 @@ class CPPType : NonCopyable, NonMovable {
void relocate_to_uninitialized_n(void *src, void *dst, int64_t n) const
{
- BLI_assert(src != dst);
+ BLI_assert(n == 0 || src != dst);
BLI_assert(n == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(n == 0 || this->pointer_can_point_to_instance(dst));
@@ -484,7 +484,7 @@ class CPPType : NonCopyable, NonMovable {
void relocate_to_uninitialized_indices(void *src, void *dst, IndexMask mask) const
{
- BLI_assert(src != dst);
+ BLI_assert(mask.size() == 0 || src != dst);
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(src));
BLI_assert(mask.size() == 0 || this->pointer_can_point_to_instance(dst));
diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh
index 71b05754717..ba2d1d0edd3 100644
--- a/source/blender/functions/FN_multi_function_params.hh
+++ b/source/blender/functions/FN_multi_function_params.hh
@@ -49,52 +49,56 @@ class MFParamsBuilder {
MFParamsBuilder(const class MultiFunction &fn, int64_t min_array_size);
- template<typename T> void add_readonly_single_input(const T *value)
+ template<typename T> void add_readonly_single_input(const T *value, StringRef expected_name = "")
{
- this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_));
+ this->add_readonly_single_input(GVSpan::FromSingle(CPPType::get<T>(), value, min_array_size_),
+ expected_name);
}
- void add_readonly_single_input(GVSpan ref)
+ void add_readonly_single_input(GVSpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()));
+ this->assert_current_param_type(MFParamType::ForSingleInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
virtual_spans_.append(ref);
}
- void add_readonly_vector_input(GVArraySpan ref)
+ void add_readonly_vector_input(GVArraySpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()));
+ this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
virtual_array_spans_.append(ref);
}
- template<typename T> void add_uninitialized_single_output(T *value)
+ template<typename T> void add_uninitialized_single_output(T *value, StringRef expected_name = "")
{
- this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1));
+ this->add_uninitialized_single_output(GMutableSpan(CPPType::get<T>(), value, 1),
+ expected_name);
}
- void add_uninitialized_single_output(GMutableSpan ref)
+ void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()));
+ this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
mutable_spans_.append(ref);
}
- void add_vector_output(GVectorArray &vector_array)
+ void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()));
+ this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()),
+ expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
vector_arrays_.append(&vector_array);
}
- void add_single_mutable(GMutableSpan ref)
+ void add_single_mutable(GMutableSpan ref, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()));
+ this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name);
BLI_assert(ref.size() >= min_array_size_);
mutable_spans_.append(ref);
}
- void add_vector_mutable(GVectorArray &vector_array)
+ void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "")
{
- this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()));
+ this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()),
+ expected_name);
BLI_assert(vector_array.size() >= min_array_size_);
vector_arrays_.append(&vector_array);
}
@@ -118,11 +122,17 @@ class MFParamsBuilder {
}
private:
- void assert_current_param_type(MFParamType param_type)
+ void assert_current_param_type(MFParamType param_type, StringRef expected_name = "")
{
- UNUSED_VARS_NDEBUG(param_type);
+ UNUSED_VARS_NDEBUG(param_type, expected_name);
#ifdef DEBUG
int param_index = this->current_param_index();
+
+ if (expected_name != "") {
+ StringRef actual_name = signature_->param_names[param_index];
+ BLI_assert(actual_name == expected_name);
+ }
+
MFParamType expected_type = signature_->param_types[param_index];
BLI_assert(expected_type == param_type);
#endif
diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh
index fd92bb2ff55..ef51ddbaf24 100644
--- a/source/blender/functions/FN_multi_function_signature.hh
+++ b/source/blender/functions/FN_multi_function_signature.hh
@@ -31,10 +31,9 @@ namespace blender::fn {
struct MFSignature {
std::string function_name;
- /* Use RawAllocator so that a MultiFunction can have static storage duration. */
- RawVector<std::string> param_names;
- RawVector<MFParamType> param_types;
- RawVector<int> param_data_indices;
+ Vector<std::string> param_names;
+ Vector<MFParamType> param_types;
+ Vector<int> param_data_indices;
bool depends_on_context = false;
int data_index(int param_index) const
diff --git a/source/blender/functions/FN_spans.hh b/source/blender/functions/FN_spans.hh
index 3ceb78ea6bd..76380f46e91 100644
--- a/source/blender/functions/FN_spans.hh
+++ b/source/blender/functions/FN_spans.hh
@@ -50,12 +50,12 @@ namespace blender::fn {
class GSpan {
private:
const CPPType *type_;
- const void *buffer_;
+ const void *data_;
int64_t size_;
public:
GSpan(const CPPType &type, const void *buffer, int64_t size)
- : type_(&type), buffer_(buffer), size_(size)
+ : type_(&type), data_(buffer), size_(size)
{
BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
@@ -86,21 +86,21 @@ class GSpan {
return size_;
}
- const void *buffer() const
+ const void *data() const
{
- return buffer_;
+ return data_;
}
const void *operator[](int64_t index) const
{
BLI_assert(index < size_);
- return POINTER_OFFSET(buffer_, type_->size() * index);
+ return POINTER_OFFSET(data_, type_->size() * index);
}
template<typename T> Span<T> typed() const
{
BLI_assert(type_->is<T>());
- return Span<T>((const T *)buffer_, size_);
+ return Span<T>((const T *)data_, size_);
}
};
@@ -111,12 +111,12 @@ class GSpan {
class GMutableSpan {
private:
const CPPType *type_;
- void *buffer_;
+ void *data_;
int64_t size_;
public:
GMutableSpan(const CPPType &type, void *buffer, int64_t size)
- : type_(&type), buffer_(buffer), size_(size)
+ : type_(&type), data_(buffer), size_(size)
{
BLI_assert(size >= 0);
BLI_assert(buffer != nullptr || size == 0);
@@ -135,7 +135,7 @@ class GMutableSpan {
operator GSpan() const
{
- return GSpan(*type_, buffer_, size_);
+ return GSpan(*type_, data_, size_);
}
const CPPType &type() const
@@ -153,21 +153,21 @@ class GMutableSpan {
return size_;
}
- void *buffer()
+ void *data()
{
- return buffer_;
+ return data_;
}
void *operator[](int64_t index)
{
BLI_assert(index < size_);
- return POINTER_OFFSET(buffer_, type_->size() * index);
+ return POINTER_OFFSET(data_, type_->size() * index);
}
template<typename T> MutableSpan<T> typed()
{
BLI_assert(type_->is<T>());
- return MutableSpan<T>((T *)buffer_, size_);
+ return MutableSpan<T>((T *)data_, size_);
}
};
@@ -208,6 +208,20 @@ template<typename T> struct VSpanBase {
return false;
}
+ bool is_full_array() const
+ {
+ switch (category_) {
+ case VSpanCategory::Single:
+ return virtual_size_ == 1;
+ case VSpanCategory::FullArray:
+ return true;
+ case VSpanCategory::FullPointerArray:
+ return virtual_size_ <= 1;
+ }
+ BLI_assert(false);
+ return false;
+ }
+
bool is_empty() const
{
return this->virtual_size_ == 0;
@@ -284,6 +298,22 @@ template<typename T> class VSpan : public VSpanBase<T> {
BLI_assert(false);
return *this->data_.single.data;
}
+
+ const T &as_single_element() const
+ {
+ BLI_assert(this->is_single_element());
+ return (*this)[0];
+ }
+
+ Span<T> as_full_array() const
+ {
+ BLI_assert(this->is_full_array());
+ if (this->virtual_size_ == 0) {
+ return Span<T>();
+ }
+ const T *data = &(*this)[0];
+ return Span<T>(data, this->virtual_size_);
+ }
};
/**
@@ -310,7 +340,7 @@ class GVSpan : public VSpanBase<void> {
this->type_ = &values.type();
this->virtual_size_ = values.size();
this->category_ = VSpanCategory::FullArray;
- this->data_.full_array.data = values.buffer();
+ this->data_.full_array.data = values.data();
}
GVSpan(GMutableSpan values) : GVSpan(GSpan(values))
@@ -394,6 +424,16 @@ class GVSpan : public VSpanBase<void> {
return (*this)[0];
}
+ GSpan as_full_array() const
+ {
+ BLI_assert(this->is_full_array());
+ if (this->virtual_size_ == 0) {
+ return GSpan(*this->type_);
+ }
+ const void *data = (*this)[0];
+ return GSpan(*this->type_, data, this->virtual_size_);
+ }
+
void materialize_to_uninitialized(void *dst) const
{
this->materialize_to_uninitialized(IndexRange(virtual_size_), dst);
diff --git a/source/blender/functions/intern/attributes_ref.cc b/source/blender/functions/intern/attributes_ref.cc
index 7bfcc69671a..9f1e7fa65e5 100644
--- a/source/blender/functions/intern/attributes_ref.cc
+++ b/source/blender/functions/intern/attributes_ref.cc
@@ -25,8 +25,12 @@ AttributesInfoBuilder::~AttributesInfoBuilder()
}
}
-void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value)
+bool AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void *default_value)
{
+ if (name.size() == 0) {
+ std::cout << "Warning: Tried to add an attribute with empty name.\n";
+ return false;
+ }
if (names_.add_as(name)) {
types_.append(&type);
@@ -36,11 +40,15 @@ void AttributesInfoBuilder::add(StringRef name, const CPPType &type, const void
void *dst = allocator_.allocate(type.size(), type.alignment());
type.copy_to_uninitialized(default_value, dst);
defaults_.append(dst);
+ return true;
}
- else {
- /* The same name can be added more than once as long as the type is always the same. */
- BLI_assert(types_[names_.index_of_as(name)] == &type);
+
+ const CPPType &stored_type = *types_[names_.index_of_as(name)];
+ if (stored_type != type) {
+ std::cout << "Warning: Tried to add an attribute twice with different types (" << name << ": "
+ << stored_type.name() << ", " << type.name() << ").\n";
}
+ return false;
}
AttributesInfo::AttributesInfo(const AttributesInfoBuilder &builder)
diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc
index 06084247e66..c9e8b88ba03 100644
--- a/source/blender/functions/intern/multi_function_builder.cc
+++ b/source/blender/functions/intern/multi_function_builder.cc
@@ -34,7 +34,7 @@ void CustomMF_GenericConstant::call(IndexMask mask,
MFContext UNUSED(context)) const
{
GMutableSpan output = params.uninitialized_single_output(0);
- type_.fill_uninitialized_indices(value_, output.buffer(), mask);
+ type_.fill_uninitialized_indices(value_, output.data(), mask);
}
uint64_t CustomMF_GenericConstant::hash() const
@@ -111,7 +111,7 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext UNU
if (param_type.data_type().is_single()) {
GMutableSpan span = params.uninitialized_single_output(param_index);
const CPPType &type = span.type();
- type.fill_uninitialized_indices(type.default_value(), span.buffer(), mask);
+ type.fill_uninitialized_indices(type.default_value(), span.data(), mask);
}
}
}
diff --git a/source/blender/functions/intern/multi_function_network_evaluation.cc b/source/blender/functions/intern/multi_function_network_evaluation.cc
index 58577e31c42..480a048b510 100644
--- a/source/blender/functions/intern/multi_function_network_evaluation.cc
+++ b/source/blender/functions/intern/multi_function_network_evaluation.cc
@@ -390,7 +390,7 @@ BLI_NOINLINE void MFNetworkEvaluator::initialize_remaining_outputs(
case MFDataType::Single: {
GVSpan values = storage.get_single_input__full(*socket);
GMutableSpan output_values = params.uninitialized_single_output(param_index);
- values.materialize_to_uninitialized(storage.mask(), output_values.buffer());
+ values.materialize_to_uninitialized(storage.mask(), output_values.data());
break;
}
case MFDataType::Vector: {
@@ -519,16 +519,16 @@ MFNetworkEvaluationStorage::~MFNetworkEvaluationStorage()
if (any_value == nullptr) {
continue;
}
- else if (any_value->type == ValueType::OwnSingle) {
+ if (any_value->type == ValueType::OwnSingle) {
OwnSingleValue *value = (OwnSingleValue *)any_value;
GMutableSpan span = value->span;
const CPPType &type = span.type();
if (value->is_single_allocated) {
- type.destruct(span.buffer());
+ type.destruct(span.data());
}
else {
- type.destruct_indices(span.buffer(), mask_);
- MEM_freeN(span.buffer());
+ type.destruct_indices(span.data(), mask_);
+ MEM_freeN(span.data());
}
}
else if (any_value->type == ValueType::OwnVector) {
@@ -634,11 +634,11 @@ void MFNetworkEvaluationStorage::finish_input_socket(const MFInputSocket &socket
GMutableSpan span = value->span;
const CPPType &type = span.type();
if (value->is_single_allocated) {
- type.destruct(span.buffer());
+ type.destruct(span.data());
}
else {
- type.destruct_indices(span.buffer(), mask_);
- MEM_freeN(span.buffer());
+ type.destruct_indices(span.data(), mask_);
+ MEM_freeN(span.data());
}
value_per_output_id_[origin.id()] = nullptr;
}
@@ -710,10 +710,9 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__full(const MFOutputS
return span;
}
- else {
- BLI_assert(any_value->type == ValueType::OutputSingle);
- return ((OutputSingleValue *)any_value)->span;
- }
+
+ BLI_assert(any_value->type == ValueType::OutputSingle);
+ return ((OutputSingleValue *)any_value)->span;
}
GMutableSpan MFNetworkEvaluationStorage::get_single_output__single(const MFOutputSocket &socket)
@@ -729,12 +728,11 @@ GMutableSpan MFNetworkEvaluationStorage::get_single_output__single(const MFOutpu
return value->span;
}
- else {
- BLI_assert(any_value->type == ValueType::OutputSingle);
- GMutableSpan span = ((OutputSingleValue *)any_value)->span;
- BLI_assert(span.size() == 1);
- return span;
- }
+
+ BLI_assert(any_value->type == ValueType::OutputSingle);
+ GMutableSpan span = ((OutputSingleValue *)any_value)->span;
+ BLI_assert(span.size() == 1);
+ return span;
}
GVectorArray &MFNetworkEvaluationStorage::get_vector_output__full(const MFOutputSocket &socket)
@@ -749,10 +747,9 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__full(const MFOutput
return *value->vector_array;
}
- else {
- BLI_assert(any_value->type == ValueType::OutputVector);
- return *((OutputVectorValue *)any_value)->vector_array;
- }
+
+ BLI_assert(any_value->type == ValueType::OutputVector);
+ return *((OutputVectorValue *)any_value)->vector_array;
}
GVectorArray &MFNetworkEvaluationStorage::get_vector_output__single(const MFOutputSocket &socket)
@@ -767,12 +764,11 @@ GVectorArray &MFNetworkEvaluationStorage::get_vector_output__single(const MFOutp
return *value->vector_array;
}
- else {
- BLI_assert(any_value->type == ValueType::OutputVector);
- GVectorArray &vector_array = *((OutputVectorValue *)any_value)->vector_array;
- BLI_assert(vector_array.size() == 1);
- return vector_array;
- }
+
+ BLI_assert(any_value->type == ValueType::OutputVector);
+ GVectorArray &vector_array = *((OutputVectorValue *)any_value)->vector_array;
+ BLI_assert(vector_array.size() == 1);
+ return vector_array;
}
GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputSocket &input,
@@ -791,7 +787,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS
BLI_assert(to_any_value->type == ValueType::OutputSingle);
GMutableSpan span = ((OutputSingleValue *)to_any_value)->span;
GVSpan virtual_span = this->get_single_input__full(input);
- virtual_span.materialize_to_uninitialized(mask_, span.buffer());
+ virtual_span.materialize_to_uninitialized(mask_, span.data());
return span;
}
@@ -808,7 +804,7 @@ GMutableSpan MFNetworkEvaluationStorage::get_mutable_single__full(const MFInputS
GVSpan virtual_span = this->get_single_input__full(input);
void *new_buffer = MEM_mallocN_aligned(min_array_size_ * type.size(), type.alignment(), AT);
GMutableSpan new_array_ref(type, new_buffer, min_array_size_);
- virtual_span.materialize_to_uninitialized(mask_, new_array_ref.buffer());
+ virtual_span.materialize_to_uninitialized(mask_, new_array_ref.data());
OwnSingleValue *new_value = allocator_.construct<OwnSingleValue>(
new_array_ref, to.targets().size(), false);
@@ -953,17 +949,16 @@ GVSpan MFNetworkEvaluationStorage::get_single_input__full(const MFInputSocket &s
if (any_value->type == ValueType::OwnSingle) {
OwnSingleValue *value = (OwnSingleValue *)any_value;
if (value->is_single_allocated) {
- return GVSpan::FromSingle(value->span.type(), value->span.buffer(), min_array_size_);
- }
- else {
- return value->span;
+ return GVSpan::FromSingle(value->span.type(), value->span.data(), min_array_size_);
}
+
+ return value->span;
}
- else if (any_value->type == ValueType::InputSingle) {
+ if (any_value->type == ValueType::InputSingle) {
InputSingleValue *value = (InputSingleValue *)any_value;
return value->virtual_span;
}
- else if (any_value->type == ValueType::OutputSingle) {
+ if (any_value->type == ValueType::OutputSingle) {
OutputSingleValue *value = (OutputSingleValue *)any_value;
BLI_assert(value->is_computed);
return value->span;
@@ -984,12 +979,12 @@ GVSpan MFNetworkEvaluationStorage::get_single_input__single(const MFInputSocket
BLI_assert(value->span.size() == 1);
return value->span;
}
- else if (any_value->type == ValueType::InputSingle) {
+ if (any_value->type == ValueType::InputSingle) {
InputSingleValue *value = (InputSingleValue *)any_value;
BLI_assert(value->virtual_span.is_single_element());
return value->virtual_span;
}
- else if (any_value->type == ValueType::OutputSingle) {
+ if (any_value->type == ValueType::OutputSingle) {
OutputSingleValue *value = (OutputSingleValue *)any_value;
BLI_assert(value->is_computed);
BLI_assert(value->span.size() == 1);
@@ -1012,15 +1007,14 @@ GVArraySpan MFNetworkEvaluationStorage::get_vector_input__full(const MFInputSock
GSpan span = (*value->vector_array)[0];
return GVArraySpan(span, min_array_size_);
}
- else {
- return *value->vector_array;
- }
+
+ return *value->vector_array;
}
- else if (any_value->type == ValueType::InputVector) {
+ if (any_value->type == ValueType::InputVector) {
InputVectorValue *value = (InputVectorValue *)any_value;
return value->virtual_array_span;
}
- else if (any_value->type == ValueType::OutputVector) {
+ if (any_value->type == ValueType::OutputVector) {
OutputVectorValue *value = (OutputVectorValue *)any_value;
return *value->vector_array;
}
@@ -1040,12 +1034,12 @@ GVArraySpan MFNetworkEvaluationStorage::get_vector_input__single(const MFInputSo
BLI_assert(value->vector_array->size() == 1);
return *value->vector_array;
}
- else if (any_value->type == ValueType::InputVector) {
+ if (any_value->type == ValueType::InputVector) {
InputVectorValue *value = (InputVectorValue *)any_value;
BLI_assert(value->virtual_array_span.is_single_array());
return value->virtual_array_span;
}
- else if (any_value->type == ValueType::OutputVector) {
+ if (any_value->type == ValueType::OutputVector) {
OutputVectorValue *value = (OutputVectorValue *)any_value;
BLI_assert(value->vector_array->size() == 1);
return *value->vector_array;
diff --git a/source/blender/functions/intern/multi_function_network_optimization.cc b/source/blender/functions/intern/multi_function_network_optimization.cc
index f1e047f01a1..e53b9a2c648 100644
--- a/source/blender/functions/intern/multi_function_network_optimization.cc
+++ b/source/blender/functions/intern/multi_function_network_optimization.cc
@@ -28,6 +28,7 @@
#include "BLI_disjoint_set.hh"
#include "BLI_ghash.h"
#include "BLI_map.hh"
+#include "BLI_multi_value_map.hh"
#include "BLI_rand.h"
#include "BLI_stack.hh"
@@ -44,9 +45,8 @@ static bool set_tag_and_check_if_modified(bool &tag, bool new_value)
tag = new_value;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
static Array<bool> mask_nodes_to_the_left(MFNetwork &network, Span<MFNode *> nodes)
@@ -265,7 +265,7 @@ static Array<MFOutputSocket *> add_constant_folded_sockets(const MultiFunction &
case MFDataType::Single: {
const CPPType &cpp_type = data_type.single_type();
GMutableSpan array = params.computed_array(param_index);
- void *buffer = array.buffer();
+ void *buffer = array.data();
resources.add(buffer, array.type().destruct_cb(), AT);
constant_fn = &resources.construct<CustomMF_GenericConstant>(AT, cpp_type, buffer);
@@ -403,15 +403,15 @@ static Array<uint64_t> compute_node_hashes(MFNetwork &network)
return node_hashes;
}
-static Map<uint64_t, Vector<MFNode *, 1>> group_nodes_by_hash(MFNetwork &network,
- Span<uint64_t> node_hashes)
+static MultiValueMap<uint64_t, MFNode *> group_nodes_by_hash(MFNetwork &network,
+ Span<uint64_t> node_hashes)
{
- Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash;
+ MultiValueMap<uint64_t, MFNode *> nodes_by_hash;
for (int id : IndexRange(network.node_id_amount())) {
MFNode *node = network.node_or_null_by_id(id);
if (node != nullptr) {
uint64_t node_hash = node_hashes[id];
- nodes_by_hash.lookup_or_add_default(node_hash).append(node);
+ nodes_by_hash.add(node_hash, node);
}
}
return nodes_by_hash;
@@ -456,7 +456,7 @@ static bool nodes_output_same_values(DisjointSet &cache, const MFNode &a, const
}
static void relink_duplicate_nodes(MFNetwork &network,
- Map<uint64_t, Vector<MFNode *, 1>> &nodes_by_hash)
+ MultiValueMap<uint64_t, MFNode *> &nodes_by_hash)
{
DisjointSet same_node_cache{network.node_id_amount()};
@@ -494,7 +494,7 @@ static void relink_duplicate_nodes(MFNetwork &network,
void common_subnetwork_elimination(MFNetwork &network)
{
Array<uint64_t> node_hashes = compute_node_hashes(network);
- Map<uint64_t, Vector<MFNode *, 1>> nodes_by_hash = group_nodes_by_hash(network, node_hashes);
+ MultiValueMap<uint64_t, MFNode *> nodes_by_hash = group_nodes_by_hash(network, node_hashes);
relink_duplicate_nodes(network, nodes_by_hash);
}
diff --git a/source/blender/functions/tests/FN_array_spans_test.cc b/source/blender/functions/tests/FN_array_spans_test.cc
new file mode 100644
index 00000000000..9a632b58be8
--- /dev/null
+++ b/source/blender/functions/tests/FN_array_spans_test.cc
@@ -0,0 +1,132 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_array_spans.hh"
+#include "FN_generic_vector_array.hh"
+
+#include "BLI_array.hh"
+
+namespace blender::fn::tests {
+
+TEST(virtual_array_span, EmptyConstructor)
+{
+ VArraySpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_array_span, SingleArrayConstructor)
+{
+ std::array<int, 4> values = {3, 4, 5, 6};
+ VArraySpan<int> span{Span<int>(values), 3};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 4);
+ EXPECT_EQ(span[2].size(), 4);
+ EXPECT_EQ(span[0][0], 3);
+ EXPECT_EQ(span[0][1], 4);
+ EXPECT_EQ(span[0][2], 5);
+ EXPECT_EQ(span[0][3], 6);
+ EXPECT_EQ(span[1][3], 6);
+ EXPECT_EQ(span[2][1], 4);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 4);
+ EXPECT_EQ(converted[1][2], &values[2]);
+}
+
+TEST(virtual_array_span, MultipleArrayConstructor)
+{
+ std::array<int, 4> values0 = {1, 2, 3, 4};
+ std::array<int, 2> values1 = {6, 7};
+ std::array<int, 1> values2 = {8};
+ std::array<const int *, 3> starts = {values0.data(), values1.data(), values2.data()};
+ std::array<int64_t, 3> sizes{values0.size(), values1.size(), values2.size()};
+
+ VArraySpan<int> span{starts, sizes};
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0].size(), 4);
+ EXPECT_EQ(span[1].size(), 2);
+ EXPECT_EQ(span[2].size(), 1);
+ EXPECT_EQ(&span[0][0], values0.data());
+ EXPECT_EQ(&span[1][0], values1.data());
+ EXPECT_EQ(&span[2][0], values2.data());
+ EXPECT_EQ(span[2][0], 8);
+ EXPECT_EQ(span[1][1], 7);
+
+ GVArraySpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0].size(), 4);
+ EXPECT_EQ(converted[1].size(), 2);
+ EXPECT_EQ(converted[2].size(), 1);
+ EXPECT_EQ(converted[0][0], values0.data());
+ EXPECT_EQ(converted[1][1], values1.data() + 1);
+}
+
+TEST(generic_virtual_array_span, TypeConstructor)
+{
+ GVArraySpan span{CPPType::get<int32_t>()};
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_array_span, GSpanConstructor)
+{
+ std::array<std::string, 3> values = {"hello", "world", "test"};
+ GVArraySpan span{GSpan(CPPType::get<std::string>(), values.data(), 3), 5};
+ EXPECT_EQ(span.size(), 5);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0][0], values.data());
+ EXPECT_EQ(span[1][0], values.data());
+ EXPECT_EQ(span[4][0], values.data());
+ EXPECT_EQ(span[0].size(), 3);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(*(std::string *)span[3][1], "world");
+
+ VArraySpan converted = span.typed<std::string>();
+ EXPECT_EQ(converted.size(), 5);
+ EXPECT_EQ(converted[0][0], "hello");
+ EXPECT_EQ(converted[1][0], "hello");
+ EXPECT_EQ(converted[4][0], "hello");
+ EXPECT_EQ(converted[0].size(), 3);
+ EXPECT_EQ(converted[2].size(), 3);
+}
+
+TEST(generic_virtual_array_span, IsSingleArray1)
+{
+ Array<int> values = {5, 6, 7};
+ GVArraySpan span{GSpan(values.as_span()), 4};
+ EXPECT_TRUE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_TRUE(converted.is_single_array());
+}
+
+TEST(generic_virtual_array_span, IsSingleArray2)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ GVectorArrayRef<int> vectors_ref = vectors;
+ vectors_ref.append(1, 4);
+
+ GVArraySpan span = vectors;
+ EXPECT_FALSE(span.is_single_array());
+
+ VArraySpan converted = span.typed<int>();
+ EXPECT_FALSE(converted.is_single_array());
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_attributes_ref_test.cc b/source/blender/functions/tests/FN_attributes_ref_test.cc
new file mode 100644
index 00000000000..3a5e4743c1e
--- /dev/null
+++ b/source/blender/functions/tests/FN_attributes_ref_test.cc
@@ -0,0 +1,97 @@
+/* Apache License, Version 2.0 */
+
+#include "BLI_float3.hh"
+#include "FN_attributes_ref.hh"
+
+#include "testing/testing.h"
+
+namespace blender::fn::tests {
+
+TEST(attributes_info, BuildEmpty)
+{
+ AttributesInfoBuilder info_builder;
+ AttributesInfo info{info_builder};
+
+ EXPECT_EQ(info.size(), 0);
+}
+
+TEST(attributes_info, AddSameNameTwice)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<int>("A", 4);
+ info_builder.add<int>("A", 5);
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.size(), 1);
+ EXPECT_TRUE(info.has_attribute("A", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("B", CPPType::get<int>()));
+ EXPECT_FALSE(info.has_attribute("A", CPPType::get<float>()));
+ EXPECT_EQ(info.default_of<int>("A"), 4);
+ EXPECT_EQ(info.name_of(0), "A");
+ EXPECT_EQ(info.index_range().start(), 0);
+ EXPECT_EQ(info.index_range().one_after_last(), 1);
+}
+
+TEST(attributes_info, BuildWithDefaultString)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add("A", CPPType::get<std::string>());
+ AttributesInfo info{info_builder};
+ EXPECT_EQ(info.default_of<std::string>("A"), "");
+}
+
+TEST(attributes_info, BuildWithGivenDefault)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<std::string>("A", "hello world");
+ AttributesInfo info{info_builder};
+ const void *default_value = info.default_of("A");
+ EXPECT_EQ(*(const std::string *)default_value, "hello world");
+ EXPECT_EQ(info.type_of("A"), CPPType::get<std::string>());
+}
+
+TEST(mutable_attributes_ref, ComplexTest)
+{
+ AttributesInfoBuilder info_builder;
+ info_builder.add<float3>("Position", {0, 0, 10});
+ info_builder.add<uint>("ID", 0);
+ info_builder.add<float>("Size", 0.5f);
+ info_builder.add<std::string>("Name", "<no name>");
+ AttributesInfo info{info_builder};
+
+ int amount = 5;
+ Array<float3> positions(amount);
+ Array<uint> ids(amount, 0);
+ Array<float> sizes(amount);
+ Array<std::string> names(amount);
+
+ Array<void *> buffers = {positions.data(), ids.data(), sizes.data(), names.data()};
+ MutableAttributesRef attributes{info, buffers, IndexRange(1, 3)};
+ EXPECT_EQ(attributes.size(), 3);
+ EXPECT_EQ(attributes.info().size(), 4);
+ EXPECT_EQ(attributes.get("Position").data(), positions.data() + 1);
+ EXPECT_EQ(attributes.get("ID").data(), ids.data() + 1);
+ EXPECT_EQ(attributes.get("Size").data(), sizes.data() + 1);
+ EXPECT_EQ(attributes.get("Name").data(), names.data() + 1);
+
+ EXPECT_EQ(attributes.get("ID").size(), 3);
+ EXPECT_EQ(attributes.get<uint>("ID").size(), 3);
+
+ EXPECT_EQ(ids[2], 0);
+ MutableSpan<uint> ids_span = attributes.get<uint>("ID");
+ ids_span[1] = 42;
+ EXPECT_EQ(ids[2], 42);
+
+ EXPECT_FALSE(attributes.try_get<int>("not existant").has_value());
+ EXPECT_FALSE(attributes.try_get<int>("Position").has_value());
+ EXPECT_TRUE(attributes.try_get<float3>("Position").has_value());
+ EXPECT_FALSE(attributes.try_get("not existant", CPPType::get<int>()).has_value());
+ EXPECT_FALSE(attributes.try_get("Position", CPPType::get<int>()).has_value());
+ EXPECT_TRUE(attributes.try_get("Position", CPPType::get<float3>()).has_value());
+
+ MutableAttributesRef sliced = attributes.slice(IndexRange(1, 2));
+ EXPECT_EQ(sliced.size(), 2);
+ sliced.get<uint>("ID")[0] = 100;
+ EXPECT_EQ(ids[2], 100);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_cpp_type_test.cc b/source/blender/functions/tests/FN_cpp_type_test.cc
new file mode 100644
index 00000000000..29368b251cc
--- /dev/null
+++ b/source/blender/functions/tests/FN_cpp_type_test.cc
@@ -0,0 +1,325 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_cpp_type.hh"
+
+namespace blender::fn::tests {
+
+static const int default_constructed_value = 1;
+static const int copy_constructed_value = 2;
+static const int move_constructed_value = 3;
+static const int copy_constructed_from_value = 4;
+static const int move_constructed_from_value = 5;
+static const int copy_assigned_value = 6;
+static const int copy_assigned_from_value = 7;
+static const int move_assigned_value = 8;
+static const int move_assigned_from_value = 9;
+static const int destructed_value = 10;
+
+struct TestType {
+ mutable volatile int value;
+
+ TestType()
+ {
+ value = default_constructed_value;
+ }
+
+ ~TestType()
+ {
+ value = destructed_value;
+ }
+
+ TestType(const TestType &other)
+ {
+ value = copy_constructed_value;
+ other.value = copy_constructed_from_value;
+ }
+
+ TestType(TestType &&other) noexcept
+ {
+ value = move_constructed_value;
+ other.value = move_constructed_from_value;
+ }
+
+ TestType &operator=(const TestType &other)
+ {
+ value = copy_assigned_value;
+ other.value = copy_assigned_from_value;
+ return *this;
+ }
+
+ TestType &operator=(TestType &&other) noexcept
+ {
+ value = move_assigned_value;
+ other.value = move_assigned_from_value;
+ return *this;
+ }
+
+ friend std::ostream &operator<<(std::ostream &stream, const TestType &value)
+ {
+ stream << value.value;
+ return stream;
+ }
+
+ friend bool operator==(const TestType &UNUSED(a), const TestType &UNUSED(b))
+ {
+ return false;
+ }
+
+ uint64_t hash() const
+ {
+ return 0;
+ }
+};
+
+} // namespace blender::fn::tests
+
+MAKE_CPP_TYPE(TestType, blender::fn::tests::TestType)
+
+namespace blender::fn::tests {
+
+const CPPType &CPPType_TestType = CPPType::get<TestType>();
+
+TEST(cpp_type, Size)
+{
+ EXPECT_EQ(CPPType_TestType.size(), sizeof(TestType));
+}
+
+TEST(cpp_type, Alignment)
+{
+ EXPECT_EQ(CPPType_TestType.alignment(), alignof(TestType));
+}
+
+TEST(cpp_type, Is)
+{
+ EXPECT_TRUE(CPPType_TestType.is<TestType>());
+ EXPECT_FALSE(CPPType_TestType.is<int>());
+}
+
+TEST(cpp_type, DefaultConstruction)
+{
+ int buffer[10] = {0};
+ CPPType_TestType.construct_default((void *)buffer);
+ EXPECT_EQ(buffer[0], default_constructed_value);
+ EXPECT_EQ(buffer[1], 0);
+ CPPType_TestType.construct_default_n((void *)buffer, 3);
+ EXPECT_EQ(buffer[0], default_constructed_value);
+ EXPECT_EQ(buffer[1], default_constructed_value);
+ EXPECT_EQ(buffer[2], default_constructed_value);
+ EXPECT_EQ(buffer[3], 0);
+ CPPType_TestType.construct_default_indices((void *)buffer, {2, 5, 7});
+ EXPECT_EQ(buffer[2], default_constructed_value);
+ EXPECT_EQ(buffer[4], 0);
+ EXPECT_EQ(buffer[5], default_constructed_value);
+ EXPECT_EQ(buffer[6], 0);
+ EXPECT_EQ(buffer[7], default_constructed_value);
+ EXPECT_EQ(buffer[8], 0);
+}
+
+TEST(cpp_type, Destruct)
+{
+ int buffer[10] = {0};
+ CPPType_TestType.destruct((void *)buffer);
+ EXPECT_EQ(buffer[0], destructed_value);
+ EXPECT_EQ(buffer[1], 0);
+ CPPType_TestType.destruct_n((void *)buffer, 3);
+ EXPECT_EQ(buffer[0], destructed_value);
+ EXPECT_EQ(buffer[1], destructed_value);
+ EXPECT_EQ(buffer[2], destructed_value);
+ EXPECT_EQ(buffer[3], 0);
+ CPPType_TestType.destruct_indices((void *)buffer, {2, 5, 7});
+ EXPECT_EQ(buffer[2], destructed_value);
+ EXPECT_EQ(buffer[4], 0);
+ EXPECT_EQ(buffer[5], destructed_value);
+ EXPECT_EQ(buffer[6], 0);
+ EXPECT_EQ(buffer[7], destructed_value);
+ EXPECT_EQ(buffer[8], 0);
+}
+
+TEST(cpp_type, CopyToUninitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.copy_to_uninitialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ CPPType_TestType.copy_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer1[1], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer1[2], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.copy_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[5], copy_constructed_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], copy_constructed_from_value);
+ EXPECT_EQ(buffer2[7], copy_constructed_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, CopyToInitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.copy_to_initialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ CPPType_TestType.copy_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer1[1], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer1[2], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.copy_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[5], copy_assigned_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], copy_assigned_from_value);
+ EXPECT_EQ(buffer2[7], copy_assigned_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, RelocateToUninitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.relocate_to_uninitialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_constructed_value);
+ CPPType_TestType.relocate_to_uninitialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_constructed_value);
+ EXPECT_EQ(buffer1[1], destructed_value);
+ EXPECT_EQ(buffer2[1], move_constructed_value);
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_constructed_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.relocate_to_uninitialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_constructed_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], destructed_value);
+ EXPECT_EQ(buffer2[5], move_constructed_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], destructed_value);
+ EXPECT_EQ(buffer2[7], move_constructed_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, RelocateToInitialized)
+{
+ int buffer1[10] = {0};
+ int buffer2[10] = {0};
+ CPPType_TestType.relocate_to_initialized((void *)buffer1, (void *)buffer2);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_assigned_value);
+ CPPType_TestType.relocate_to_initialized_n((void *)buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1[0], destructed_value);
+ EXPECT_EQ(buffer2[0], move_assigned_value);
+ EXPECT_EQ(buffer1[1], destructed_value);
+ EXPECT_EQ(buffer2[1], move_assigned_value);
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_assigned_value);
+ EXPECT_EQ(buffer1[3], 0);
+ EXPECT_EQ(buffer2[3], 0);
+ CPPType_TestType.relocate_to_initialized_indices((void *)buffer1, (void *)buffer2, {2, 5, 7});
+ EXPECT_EQ(buffer1[2], destructed_value);
+ EXPECT_EQ(buffer2[2], move_assigned_value);
+ EXPECT_EQ(buffer1[4], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer1[5], destructed_value);
+ EXPECT_EQ(buffer2[5], move_assigned_value);
+ EXPECT_EQ(buffer1[6], 0);
+ EXPECT_EQ(buffer2[6], 0);
+ EXPECT_EQ(buffer1[7], destructed_value);
+ EXPECT_EQ(buffer2[7], move_assigned_value);
+ EXPECT_EQ(buffer1[8], 0);
+ EXPECT_EQ(buffer2[8], 0);
+}
+
+TEST(cpp_type, FillInitialized)
+{
+ int buffer1 = 0;
+ int buffer2[10] = {0};
+ CPPType_TestType.fill_initialized((void *)&buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1, copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer2[3], 0);
+
+ buffer1 = 0;
+ CPPType_TestType.fill_initialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
+ EXPECT_EQ(buffer1, copy_assigned_from_value);
+ EXPECT_EQ(buffer2[0], copy_assigned_value);
+ EXPECT_EQ(buffer2[1], copy_assigned_value);
+ EXPECT_EQ(buffer2[2], copy_assigned_value);
+ EXPECT_EQ(buffer2[3], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer2[5], 0);
+ EXPECT_EQ(buffer2[6], copy_assigned_value);
+ EXPECT_EQ(buffer2[7], 0);
+ EXPECT_EQ(buffer2[8], copy_assigned_value);
+ EXPECT_EQ(buffer2[9], 0);
+}
+
+TEST(cpp_type, FillUninitialized)
+{
+ int buffer1 = 0;
+ int buffer2[10] = {0};
+ CPPType_TestType.fill_uninitialized((void *)&buffer1, (void *)buffer2, 3);
+ EXPECT_EQ(buffer1, copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer2[3], 0);
+
+ buffer1 = 0;
+ CPPType_TestType.fill_uninitialized_indices((void *)&buffer1, (void *)buffer2, {1, 6, 8});
+ EXPECT_EQ(buffer1, copy_constructed_from_value);
+ EXPECT_EQ(buffer2[0], copy_constructed_value);
+ EXPECT_EQ(buffer2[1], copy_constructed_value);
+ EXPECT_EQ(buffer2[2], copy_constructed_value);
+ EXPECT_EQ(buffer2[3], 0);
+ EXPECT_EQ(buffer2[4], 0);
+ EXPECT_EQ(buffer2[5], 0);
+ EXPECT_EQ(buffer2[6], copy_constructed_value);
+ EXPECT_EQ(buffer2[7], 0);
+ EXPECT_EQ(buffer2[8], copy_constructed_value);
+ EXPECT_EQ(buffer2[9], 0);
+}
+
+TEST(cpp_type, DebugPrint)
+{
+ int value = 42;
+ std::stringstream ss;
+ CPPType::get<int32_t>().debug_print((void *)&value, ss);
+ std::string text = ss.str();
+ EXPECT_EQ(text, "42");
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_generic_vector_array_test.cc b/source/blender/functions/tests/FN_generic_vector_array_test.cc
new file mode 100644
index 00000000000..77ec05f12dc
--- /dev/null
+++ b/source/blender/functions/tests/FN_generic_vector_array_test.cc
@@ -0,0 +1,101 @@
+/* Apache License, Version 2.0 */
+
+#include "FN_generic_vector_array.hh"
+
+#include "testing/testing.h"
+
+namespace blender::fn::tests {
+
+TEST(generic_vector_array, Constructor)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ EXPECT_EQ(vectors.size(), 3);
+ EXPECT_EQ(vectors.lengths().size(), 3);
+ EXPECT_EQ(vectors.starts().size(), 3);
+ EXPECT_EQ(vectors.lengths()[0], 0);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 0);
+ EXPECT_EQ(vectors.type(), CPPType::get<int32_t>());
+}
+
+TEST(generic_vector_array, Append)
+{
+ GVectorArray vectors{CPPType::get<std::string>(), 3};
+ std::string value = "hello";
+ vectors.append(0, &value);
+ value = "world";
+ vectors.append(0, &value);
+ vectors.append(2, &value);
+
+ EXPECT_EQ(vectors.lengths()[0], 2);
+ EXPECT_EQ(vectors.lengths()[1], 0);
+ EXPECT_EQ(vectors.lengths()[2], 1);
+ EXPECT_EQ(vectors[0].size(), 2);
+ EXPECT_EQ(vectors[0].typed<std::string>()[0], "hello");
+ EXPECT_EQ(vectors[0].typed<std::string>()[1], "world");
+ EXPECT_EQ(vectors[2].typed<std::string>()[0], "world");
+}
+
+TEST(generic_vector_array, AsArraySpan)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ int value = 3;
+ vectors.append(0, &value);
+ vectors.append(0, &value);
+ value = 5;
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+ vectors.append(2, &value);
+
+ GVArraySpan span = vectors;
+ EXPECT_EQ(span.type(), CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0].size(), 2);
+ EXPECT_EQ(span[1].size(), 0);
+ EXPECT_EQ(span[2].size(), 3);
+ EXPECT_EQ(span[0].typed<int>()[1], 3);
+ EXPECT_EQ(span[2].typed<int>()[0], 5);
+}
+
+TEST(generic_vector_array, TypedRef)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 4};
+ GVectorArrayRef<int> ref = vectors.typed<int>();
+ ref.append(0, 2);
+ ref.append(0, 6);
+ ref.append(0, 7);
+ ref.append(2, 1);
+ ref.append(2, 1);
+ ref.append(3, 5);
+ ref.append(3, 6);
+
+ EXPECT_EQ(ref[0].size(), 3);
+ EXPECT_EQ(vectors[0].size(), 3);
+ EXPECT_EQ(ref[0][0], 2);
+ EXPECT_EQ(ref[0][1], 6);
+ EXPECT_EQ(ref[0][2], 7);
+ EXPECT_EQ(ref[1].size(), 0);
+ EXPECT_EQ(ref[2][0], 1);
+ EXPECT_EQ(ref[2][1], 1);
+ EXPECT_EQ(ref[3][0], 5);
+ EXPECT_EQ(ref[3][1], 6);
+}
+
+TEST(generic_vector_array, Extend)
+{
+ GVectorArray vectors{CPPType::get<int32_t>(), 3};
+ GVectorArrayRef<int> ref = vectors;
+
+ ref.extend(1, {5, 6, 7});
+ ref.extend(0, {3});
+
+ EXPECT_EQ(vectors[0].size(), 1);
+ EXPECT_EQ(vectors[1].size(), 3);
+ EXPECT_EQ(vectors[2].size(), 0);
+ EXPECT_EQ(ref[1][0], 5);
+ EXPECT_EQ(ref[1][1], 6);
+ EXPECT_EQ(ref[1][2], 7);
+ EXPECT_EQ(ref[0][0], 3);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_multi_function_network_test.cc b/source/blender/functions/tests/FN_multi_function_network_test.cc
new file mode 100644
index 00000000000..f226e0eac2e
--- /dev/null
+++ b/source/blender/functions/tests/FN_multi_function_network_test.cc
@@ -0,0 +1,255 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_multi_function_builder.hh"
+#include "FN_multi_function_network.hh"
+#include "FN_multi_function_network_evaluation.hh"
+
+namespace blender::fn::tests {
+namespace {
+
+TEST(multi_function_network, Test1)
+{
+ CustomMF_SI_SO<int, int> add_10_fn("add 10", [](int value) { return value + 10; });
+ CustomMF_SI_SI_SO<int, int, int> multiply_fn("multiply", [](int a, int b) { return a * b; });
+
+ MFNetwork network;
+
+ MFNode &node1 = network.add_function(add_10_fn);
+ MFNode &node2 = network.add_function(multiply_fn);
+ MFOutputSocket &input_socket = network.add_input("Input", MFDataType::ForSingle<int>());
+ MFInputSocket &output_socket = network.add_output("Output", MFDataType::ForSingle<int>());
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node1.output(0), node2.input(1));
+ network.add_link(node2.output(0), output_socket);
+ network.add_link(input_socket, node1.input(0));
+
+ MFNetworkEvaluator network_fn{{&input_socket}, {&output_socket}};
+
+ {
+ Array<int> values = {4, 6, 1, 2, 0};
+ Array<int> results(values.size(), 0);
+
+ MFParamsBuilder params(network_fn, values.size());
+ params.add_readonly_single_input(values.as_span());
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 2, 3, 4}, params, context);
+
+ EXPECT_EQ(results[0], 14 * 14);
+ EXPECT_EQ(results[1], 0);
+ EXPECT_EQ(results[2], 11 * 11);
+ EXPECT_EQ(results[3], 12 * 12);
+ EXPECT_EQ(results[4], 10 * 10);
+ }
+ {
+ int value = 3;
+ Array<int> results(5, 0);
+
+ MFParamsBuilder params(network_fn, results.size());
+ params.add_readonly_single_input(&value);
+ params.add_uninitialized_single_output(results.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(results[0], 0);
+ EXPECT_EQ(results[1], 13 * 13);
+ EXPECT_EQ(results[2], 13 * 13);
+ EXPECT_EQ(results[3], 0);
+ EXPECT_EQ(results[4], 13 * 13);
+ }
+}
+
+class ConcatVectorsFunction : public MultiFunction {
+ public:
+ ConcatVectorsFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Concat Vectors");
+ signature.vector_mutable<int>("A");
+ signature.vector_input<int>("B");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> a = params.vector_mutable<int>(0);
+ VArraySpan<int> b = params.readonly_vector_input<int>(1);
+
+ for (int64_t i : mask) {
+ a.extend(i, b[i]);
+ }
+ }
+};
+
+class AppendFunction : public MultiFunction {
+ public:
+ AppendFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Append");
+ signature.vector_mutable<int>("Vector");
+ signature.single_input<int>("Value");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArrayRef<int> vectors = params.vector_mutable<int>(0);
+ VSpan<int> values = params.readonly_single_input<int>(1);
+
+ for (int64_t i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+class SumVectorFunction : public MultiFunction {
+ public:
+ SumVectorFunction()
+ {
+ MFSignatureBuilder signature = this->get_builder("Sum Vector");
+ signature.vector_input<int>("Vector");
+ signature.single_output<int>("Sum");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VArraySpan<int> vectors = params.readonly_vector_input<int>(0);
+ MutableSpan<int> sums = params.uninitialized_single_output<int>(1);
+
+ for (int64_t i : mask) {
+ int sum = 0;
+ VSpan<int> vector = vectors[i];
+ for (int j = 0; j < vector.size(); j++) {
+ sum += vector[j];
+ }
+ sums[i] = sum;
+ }
+ }
+};
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<int>("Size");
+ builder.vector_output<int>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> sizes = params.readonly_single_input<int>(0, "Size");
+ GVectorArrayRef<int> ranges = params.vector_output<int>(1, "Range");
+
+ for (int64_t i : mask) {
+ int size = sizes[i];
+ for (int j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function_network, Test2)
+{
+ CustomMF_SI_SO<int, int> add_3_fn("add 3", [](int value) { return value + 3; });
+
+ ConcatVectorsFunction concat_vectors_fn;
+ AppendFunction append_fn;
+ SumVectorFunction sum_fn;
+ CreateRangeFunction create_range_fn;
+
+ MFNetwork network;
+
+ MFOutputSocket &input1 = network.add_input("Input 1", MFDataType::ForVector<int>());
+ MFOutputSocket &input2 = network.add_input("Input 2", MFDataType::ForSingle<int>());
+ MFInputSocket &output1 = network.add_output("Output 1", MFDataType::ForVector<int>());
+ MFInputSocket &output2 = network.add_output("Output 2", MFDataType::ForSingle<int>());
+
+ MFNode &node1 = network.add_function(add_3_fn);
+ MFNode &node2 = network.add_function(create_range_fn);
+ MFNode &node3 = network.add_function(concat_vectors_fn);
+ MFNode &node4 = network.add_function(sum_fn);
+ MFNode &node5 = network.add_function(append_fn);
+ MFNode &node6 = network.add_function(sum_fn);
+
+ network.add_link(input2, node1.input(0));
+ network.add_link(node1.output(0), node2.input(0));
+ network.add_link(node2.output(0), node3.input(1));
+ network.add_link(input1, node3.input(0));
+ network.add_link(input1, node4.input(0));
+ network.add_link(node4.output(0), node5.input(1));
+ network.add_link(node3.output(0), node5.input(0));
+ network.add_link(node5.output(0), node6.input(0));
+ network.add_link(node3.output(0), output1);
+ network.add_link(node6.output(0), output2);
+
+ // std::cout << network.to_dot() << "\n\n";
+
+ MFNetworkEvaluator network_fn{{&input1, &input2}, {&output1, &output2}};
+
+ {
+ Array<int> input_value_1 = {3, 6};
+ int input_value_2 = 4;
+
+ GVectorArray output_value_1(CPPType::get<int32_t>(), 5);
+ Array<int> output_value_2(5, -1);
+
+ MFParamsBuilder params(network_fn, 5);
+ params.add_readonly_vector_input(GVArraySpan(input_value_1.as_span(), 5));
+ params.add_readonly_single_input(&input_value_2);
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({1, 2, 4}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 0);
+ EXPECT_EQ(output_value_1[1].size(), 9);
+ EXPECT_EQ(output_value_1[2].size(), 9);
+ EXPECT_EQ(output_value_1[3].size(), 0);
+ EXPECT_EQ(output_value_1[4].size(), 9);
+
+ EXPECT_EQ(output_value_2[0], -1);
+ EXPECT_EQ(output_value_2[1], 39);
+ EXPECT_EQ(output_value_2[2], 39);
+ EXPECT_EQ(output_value_2[3], -1);
+ EXPECT_EQ(output_value_2[4], 39);
+ }
+ {
+ GVectorArray input_value_1(CPPType::get<int32_t>(), 3);
+ GVectorArrayRef<int> input_value_ref_1 = input_value_1;
+ input_value_ref_1.extend(0, {3, 4, 5});
+ input_value_ref_1.extend(1, {1, 2});
+
+ Array<int> input_value_2 = {4, 2, 3};
+
+ GVectorArray output_value_1(CPPType::get<int32_t>(), 3);
+ Array<int> output_value_2(3, -1);
+
+ MFParamsBuilder params(network_fn, 3);
+ params.add_readonly_vector_input(input_value_1);
+ params.add_readonly_single_input(input_value_2.as_span());
+ params.add_vector_output(output_value_1);
+ params.add_uninitialized_single_output(output_value_2.as_mutable_span());
+
+ MFContextBuilder context;
+
+ network_fn.call({0, 1, 2}, params, context);
+
+ EXPECT_EQ(output_value_1[0].size(), 10);
+ EXPECT_EQ(output_value_1[1].size(), 7);
+ EXPECT_EQ(output_value_1[2].size(), 6);
+
+ EXPECT_EQ(output_value_2[0], 45);
+ EXPECT_EQ(output_value_2[1], 16);
+ EXPECT_EQ(output_value_2[2], 15);
+ }
+}
+
+} // namespace
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc
new file mode 100644
index 00000000000..cc023bce597
--- /dev/null
+++ b/source/blender/functions/tests/FN_multi_function_test.cc
@@ -0,0 +1,387 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_multi_function.hh"
+#include "FN_multi_function_builder.hh"
+
+namespace blender::fn::tests {
+namespace {
+
+class AddFunction : public MultiFunction {
+ public:
+ AddFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add");
+ builder.single_input<int>("A");
+ builder.single_input<int>("B");
+ builder.single_output<int>("Result");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<int> a = params.readonly_single_input<int>(0, "A");
+ VSpan<int> b = params.readonly_single_input<int>(1, "B");
+ MutableSpan<int> result = params.uninitialized_single_output<int>(2, "Result");
+
+ for (int64_t i : mask) {
+ result[i] = a[i] + b[i];
+ }
+ }
+};
+
+TEST(multi_function, AddFunction)
+{
+ AddFunction fn;
+
+ Array<int> input1 = {4, 5, 6};
+ Array<int> input2 = {10, 20, 30};
+ Array<int> output(3, -1);
+
+ MFParamsBuilder params(fn, 3);
+ params.add_readonly_single_input(input1.as_span());
+ params.add_readonly_single_input(input2.as_span());
+ params.add_uninitialized_single_output(output.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2}, params, context);
+
+ EXPECT_EQ(output[0], 14);
+ EXPECT_EQ(output[1], -1);
+ EXPECT_EQ(output[2], 36);
+}
+
+class AddPrefixFunction : public MultiFunction {
+ public:
+ AddPrefixFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Add Prefix");
+ builder.single_input<std::string>("Prefix");
+ builder.single_mutable<std::string>("Strings");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<std::string> prefixes = params.readonly_single_input<std::string>(0, "Prefix");
+ MutableSpan<std::string> strings = params.single_mutable<std::string>(1, "Strings");
+
+ for (int64_t i : mask) {
+ strings[i] = prefixes[i] + strings[i];
+ }
+ }
+};
+
+TEST(multi_function, AddPrefixFunction)
+{
+ AddPrefixFunction fn;
+
+ Array<std::string> strings = {
+ "Hello",
+ "World",
+ "This is a test",
+ "Another much longer string to trigger an allocation",
+ };
+
+ std::string prefix = "AB";
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(&prefix);
+ params.add_single_mutable(strings.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(strings[0], "ABHello");
+ EXPECT_EQ(strings[1], "World");
+ EXPECT_EQ(strings[2], "ABThis is a test");
+ EXPECT_EQ(strings[3], "ABAnother much longer string to trigger an allocation");
+}
+
+class CreateRangeFunction : public MultiFunction {
+ public:
+ CreateRangeFunction()
+ {
+ MFSignatureBuilder builder = this->get_builder("Create Range");
+ builder.single_input<uint>("Size");
+ builder.vector_output<uint>("Range");
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ VSpan<uint> sizes = params.readonly_single_input<uint>(0, "Size");
+ GVectorArrayRef<uint> ranges = params.vector_output<uint>(1, "Range");
+
+ for (int64_t i : mask) {
+ uint size = sizes[i];
+ for (uint j : IndexRange(size)) {
+ ranges.append(i, j);
+ }
+ }
+ }
+};
+
+TEST(multi_function, CreateRangeFunction)
+{
+ CreateRangeFunction fn;
+
+ GVectorArray ranges(CPPType::get<uint>(), 5);
+ GVectorArrayRef<uint> ranges_ref(ranges);
+ Array<uint> sizes = {3, 0, 6, 1, 4};
+
+ MFParamsBuilder params(fn, ranges.size());
+ params.add_readonly_single_input(sizes.as_span());
+ params.add_vector_output(ranges);
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 2, 3}, params, context);
+
+ EXPECT_EQ(ranges_ref[0].size(), 3);
+ EXPECT_EQ(ranges_ref[1].size(), 0);
+ EXPECT_EQ(ranges_ref[2].size(), 6);
+ EXPECT_EQ(ranges_ref[3].size(), 1);
+ EXPECT_EQ(ranges_ref[4].size(), 0);
+
+ EXPECT_EQ(ranges_ref[0][0], 0);
+ EXPECT_EQ(ranges_ref[0][1], 1);
+ EXPECT_EQ(ranges_ref[0][2], 2);
+ EXPECT_EQ(ranges_ref[2][0], 0);
+ EXPECT_EQ(ranges_ref[2][1], 1);
+}
+
+class GenericAppendFunction : public MultiFunction {
+ public:
+ GenericAppendFunction(const CPPType &type)
+ {
+ MFSignatureBuilder builder = this->get_builder("Append");
+ builder.vector_mutable("Vector", type);
+ builder.single_input("Value", type);
+ }
+
+ void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override
+ {
+ GVectorArray &vectors = params.vector_mutable(0, "Vector");
+ GVSpan values = params.readonly_single_input(1, "Value");
+
+ for (int64_t i : mask) {
+ vectors.append(i, values[i]);
+ }
+ }
+};
+
+TEST(multi_function, GenericAppendFunction)
+{
+ GenericAppendFunction fn(CPPType::get<int32_t>());
+
+ GVectorArray vectors(CPPType::get<int32_t>(), 4);
+ GVectorArrayRef<int> vectors_ref(vectors);
+ vectors_ref.append(0, 1);
+ vectors_ref.append(0, 2);
+ vectors_ref.append(2, 6);
+ Array<int> values = {5, 7, 3, 1};
+
+ MFParamsBuilder params(fn, vectors.size());
+ params.add_vector_mutable(vectors);
+ params.add_readonly_single_input(values.as_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(vectors.size()), params, context);
+
+ EXPECT_EQ(vectors_ref[0].size(), 3);
+ EXPECT_EQ(vectors_ref[1].size(), 1);
+ EXPECT_EQ(vectors_ref[2].size(), 2);
+ EXPECT_EQ(vectors_ref[3].size(), 1);
+
+ EXPECT_EQ(vectors_ref[0][0], 1);
+ EXPECT_EQ(vectors_ref[0][1], 2);
+ EXPECT_EQ(vectors_ref[0][2], 5);
+ EXPECT_EQ(vectors_ref[1][0], 7);
+ EXPECT_EQ(vectors_ref[2][0], 6);
+ EXPECT_EQ(vectors_ref[2][1], 3);
+ EXPECT_EQ(vectors_ref[3][0], 1);
+}
+
+TEST(multi_function, CustomMF_SI_SO)
+{
+ CustomMF_SI_SO<std::string, uint> fn("strlen",
+ [](const std::string &str) { return str.size(); });
+
+ Array<std::string> strings = {"hello", "world", "test", "another test"};
+ Array<uint> sizes(strings.size(), 0);
+
+ MFParamsBuilder params(fn, strings.size());
+ params.add_readonly_single_input(strings.as_span());
+ params.add_uninitialized_single_output(sizes.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call(IndexRange(strings.size()), params, context);
+
+ EXPECT_EQ(sizes[0], 5);
+ EXPECT_EQ(sizes[1], 5);
+ EXPECT_EQ(sizes[2], 4);
+ EXPECT_EQ(sizes[3], 12);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SO)
+{
+ CustomMF_SI_SI_SO<int, int, int> fn("mul", [](int a, int b) { return a * b; });
+
+ Array<int> values_a = {4, 6, 8, 9};
+ int value_b = 10;
+ Array<int> outputs(values_a.size(), -1);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(&value_b);
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 40);
+ EXPECT_EQ(outputs[1], 60);
+ EXPECT_EQ(outputs[2], -1);
+ EXPECT_EQ(outputs[3], 90);
+}
+
+TEST(multi_function, CustomMF_SI_SI_SI_SO)
+{
+ CustomMF_SI_SI_SI_SO<int, std::string, bool, uint> fn{
+ "custom",
+ [](int a, const std::string &b, bool c) { return (uint)((uint)a + b.size() + (uint)c); }};
+
+ Array<int> values_a = {5, 7, 3, 8};
+ Array<std::string> values_b = {"hello", "world", "another", "test"};
+ Array<bool> values_c = {true, false, false, true};
+ Array<uint> outputs(values_a.size(), 0);
+
+ MFParamsBuilder params(fn, values_a.size());
+ params.add_readonly_single_input(values_a.as_span());
+ params.add_readonly_single_input(values_b.as_span());
+ params.add_readonly_single_input(values_c.as_span());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 0);
+ EXPECT_EQ(outputs[1], 12);
+ EXPECT_EQ(outputs[2], 10);
+ EXPECT_EQ(outputs[3], 13);
+}
+
+TEST(multi_function, CustomMF_SM)
+{
+ CustomMF_SM<std::string> fn("AddSuffix", [](std::string &value) { value += " test"; });
+
+ Array<std::string> values = {"a", "b", "c", "d", "e"};
+
+ MFParamsBuilder params(fn, values.size());
+ params.add_single_mutable(values.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(values[0], "a");
+ EXPECT_EQ(values[1], "b test");
+ EXPECT_EQ(values[2], "c test");
+ EXPECT_EQ(values[3], "d test");
+ EXPECT_EQ(values[4], "e");
+}
+
+TEST(multi_function, CustomMF_Constant)
+{
+ CustomMF_Constant<int> fn{42};
+
+ Array<int> outputs(4, 0);
+
+ MFParamsBuilder params(fn, outputs.size());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 2, 3}, params, context);
+
+ EXPECT_EQ(outputs[0], 42);
+ EXPECT_EQ(outputs[1], 0);
+ EXPECT_EQ(outputs[2], 42);
+ EXPECT_EQ(outputs[3], 42);
+}
+
+TEST(multi_function, CustomMF_GenericConstant)
+{
+ int value = 42;
+ CustomMF_GenericConstant fn{CPPType::get<int32_t>(), (const void *)&value};
+ EXPECT_EQ(fn.param_name(0), "42");
+
+ Array<int> outputs(4, 0);
+
+ MFParamsBuilder params(fn, outputs.size());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+
+ fn.call({0, 1, 2}, params, context);
+
+ EXPECT_EQ(outputs[0], 42);
+ EXPECT_EQ(outputs[1], 42);
+ EXPECT_EQ(outputs[2], 42);
+ EXPECT_EQ(outputs[3], 0);
+}
+
+TEST(multi_function, CustomMF_GenericConstantArray)
+{
+ std::array<int, 4> values = {3, 4, 5, 6};
+ CustomMF_GenericConstantArray fn{GSpan(Span(values))};
+ EXPECT_EQ(fn.param_name(0), "[3, 4, 5, 6, ]");
+
+ GVectorArray g_vector_array{CPPType::get<int32_t>(), 4};
+ GVectorArrayRef<int> vector_array = g_vector_array;
+
+ MFParamsBuilder params(fn, g_vector_array.size());
+ params.add_vector_output(g_vector_array);
+
+ MFContextBuilder context;
+
+ fn.call({1, 2, 3}, params, context);
+
+ EXPECT_EQ(vector_array[0].size(), 0);
+ EXPECT_EQ(vector_array[1].size(), 4);
+ EXPECT_EQ(vector_array[2].size(), 4);
+ EXPECT_EQ(vector_array[3].size(), 4);
+ for (int i = 1; i < 4; i++) {
+ EXPECT_EQ(vector_array[i][0], 3);
+ EXPECT_EQ(vector_array[i][1], 4);
+ EXPECT_EQ(vector_array[i][2], 5);
+ EXPECT_EQ(vector_array[i][3], 6);
+ }
+}
+
+TEST(multi_function, CustomMF_Convert)
+{
+ CustomMF_Convert<float, int> fn;
+
+ Array<float> inputs = {5.4f, 7.1f, 9.0f};
+ Array<int> outputs(inputs.size(), 0);
+
+ MFParamsBuilder params(fn, inputs.size());
+ params.add_readonly_single_input(inputs.as_span());
+ params.add_uninitialized_single_output(outputs.as_mutable_span());
+
+ MFContextBuilder context;
+ fn.call({0, 2}, params, context);
+
+ EXPECT_EQ(outputs[0], 5);
+ EXPECT_EQ(outputs[1], 0);
+ EXPECT_EQ(outputs[2], 9);
+}
+
+} // namespace
+} // namespace blender::fn::tests
diff --git a/source/blender/functions/tests/FN_spans_test.cc b/source/blender/functions/tests/FN_spans_test.cc
new file mode 100644
index 00000000000..fbcf1fda71e
--- /dev/null
+++ b/source/blender/functions/tests/FN_spans_test.cc
@@ -0,0 +1,222 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+#include "FN_spans.hh"
+
+namespace blender::fn::tests {
+
+TEST(generic_span, TypeConstructor)
+{
+ GSpan span(CPPType::get<float>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_EQ(span.typed<float>().size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_span, BufferAndSizeConstructor)
+{
+ int values[4] = {6, 7, 3, 2};
+ void *buffer = (void *)values;
+ GSpan span(CPPType::get<int32_t>(), buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+}
+
+TEST(generic_mutable_span, TypeConstructor)
+{
+ GMutableSpan span(CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+}
+
+TEST(generic_mutable_span, BufferAndSizeConstructor)
+{
+ int values[4] = {4, 7, 3, 5};
+ void *buffer = (void *)values;
+ GMutableSpan span(CPPType::get<int32_t>(), buffer, 4);
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span.typed<int>().size(), 4);
+ EXPECT_EQ(values[2], 3);
+ *(int *)span[2] = 10;
+ EXPECT_EQ(values[2], 10);
+ span.typed<int>()[2] = 20;
+ EXPECT_EQ(values[2], 20);
+}
+
+TEST(virtual_span, EmptyConstructor)
+{
+ VSpan<int> span;
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(virtual_span, SpanConstructor)
+{
+ std::array<int, 5> values = {7, 3, 8, 6, 4};
+ Span<int> span = values;
+ VSpan<int> virtual_span = span;
+ EXPECT_EQ(virtual_span.size(), 5);
+ EXPECT_FALSE(virtual_span.is_empty());
+ EXPECT_EQ(virtual_span[0], 7);
+ EXPECT_EQ(virtual_span[2], 8);
+ EXPECT_EQ(virtual_span[3], 6);
+ EXPECT_FALSE(virtual_span.is_single_element());
+ EXPECT_TRUE(virtual_span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 5);
+}
+
+TEST(virtual_span, PointerSpanConstructor)
+{
+ int x0 = 3;
+ int x1 = 6;
+ int x2 = 7;
+ std::array<const int *, 3> pointers = {&x0, &x2, &x1};
+ VSpan<int> span = Span<const int *>(pointers);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 3);
+ EXPECT_EQ(span[1], 7);
+ EXPECT_EQ(span[2], 6);
+ EXPECT_EQ(&span[1], &x2);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_FALSE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &x0);
+ EXPECT_EQ(converted[1], &x2);
+ EXPECT_EQ(converted[2], &x1);
+}
+
+TEST(virtual_span, SingleConstructor)
+{
+ int value = 5;
+ VSpan<int> span = VSpan<int>::FromSingle(&value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], 5);
+ EXPECT_EQ(span[1], 5);
+ EXPECT_EQ(span[2], 5);
+ EXPECT_EQ(&span[0], &value);
+ EXPECT_EQ(&span[1], &value);
+ EXPECT_EQ(&span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+ EXPECT_FALSE(span.is_full_array());
+
+ GVSpan converted(span);
+ EXPECT_EQ(converted.type(), CPPType::get<int>());
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], &value);
+ EXPECT_EQ(converted[1], &value);
+ EXPECT_EQ(converted[2], &value);
+}
+
+TEST(generic_virtual_span, TypeConstructor)
+{
+ GVSpan span(CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 0);
+ EXPECT_TRUE(span.is_empty());
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 0);
+}
+
+TEST(generic_virtual_span, GenericSpanConstructor)
+{
+ int values[4] = {3, 4, 5, 6};
+ GVSpan span{GSpan(CPPType::get<int32_t>(), values, 4)};
+ EXPECT_EQ(span.size(), 4);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_EQ(span[3], &values[3]);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ int materialized[4] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 3);
+ EXPECT_EQ(materialized[1], 4);
+ EXPECT_EQ(materialized[2], 5);
+ EXPECT_EQ(materialized[3], 6);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 4);
+ EXPECT_EQ(converted[0], 3);
+ EXPECT_EQ(converted[1], 4);
+ EXPECT_EQ(converted[2], 5);
+ EXPECT_EQ(converted[3], 6);
+}
+
+TEST(generic_virtual_span, SpanConstructor)
+{
+ std::array<int, 3> values = {6, 7, 8};
+ GVSpan span{Span<int>(values)};
+ EXPECT_EQ(span.type(), CPPType::get<int32_t>());
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_EQ(span[0], &values[0]);
+ EXPECT_EQ(span[1], &values[1]);
+ EXPECT_EQ(span[2], &values[2]);
+ EXPECT_FALSE(span.is_single_element());
+ EXPECT_TRUE(span.is_full_array());
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized(materialized);
+ EXPECT_EQ(materialized[0], 6);
+ EXPECT_EQ(materialized[1], 7);
+ EXPECT_EQ(materialized[2], 8);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 6);
+ EXPECT_EQ(converted[1], 7);
+ EXPECT_EQ(converted[2], 8);
+}
+
+TEST(generic_virtual_span, SingleConstructor)
+{
+ int value = 5;
+ GVSpan span = GVSpan::FromSingle(CPPType::get<int32_t>(), &value, 3);
+ EXPECT_EQ(span.size(), 3);
+ EXPECT_FALSE(span.is_empty());
+ EXPECT_EQ(span[0], &value);
+ EXPECT_EQ(span[1], &value);
+ EXPECT_EQ(span[2], &value);
+ EXPECT_TRUE(span.is_single_element());
+ EXPECT_EQ(span.as_single_element(), &value);
+ EXPECT_FALSE(span.is_full_array());
+
+ int materialized[3] = {0};
+ span.materialize_to_uninitialized({1, 2}, materialized);
+ EXPECT_EQ(materialized[0], 0);
+ EXPECT_EQ(materialized[1], 5);
+ EXPECT_EQ(materialized[2], 5);
+
+ VSpan<int> converted = span.typed<int>();
+ EXPECT_EQ(converted.size(), 3);
+ EXPECT_EQ(converted[0], 5);
+ EXPECT_EQ(converted[1], 5);
+ EXPECT_EQ(converted[2], 5);
+}
+
+} // namespace blender::fn::tests
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
index f7929b58650..077a454db73 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c
@@ -180,9 +180,8 @@ float get_modifier_point_weight(MDeformVert *dvert, bool inverse, int def_nr)
if (inverse == 1) {
return 1.0f;
}
- else {
- return -1.0f;
- }
+
+ return -1.0f;
}
return weight;
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
index d92721f887f..d645064475b 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c
@@ -236,7 +236,7 @@ static void generate_geometry(GpencilModifierData *md,
float rand[3][3];
for (int j = 0; j < 3; j++) {
- uint primes[3] = {2, 3, 7};
+ const uint primes[3] = {2, 3, 7};
double offset[3] = {0.0, 0.0, 0.0};
double r[3];
/* To ensure a nice distribution, we use halton sequence and offset using the seed. */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
index 56d94611b5d..bf6c47b2df5 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c
@@ -484,7 +484,7 @@ static void generate_geometry(GpencilModifierData *md,
/* Early exit */
return;
}
- else if (ctime >= end_frame) {
+ if (ctime >= end_frame) {
/* Past End - Animation finished. Display final result. */
if (reverse) {
/* 1) Reverse = Start with all, end with nothing.
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
index 03137a5cf23..21a8962b131 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c
@@ -69,7 +69,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
index 4761dc878c0..30ac18c64ae 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c
@@ -94,7 +94,7 @@ static void initData(GpencilModifierData *md)
gpmd->falloff_type = eGPHook_Falloff_Smooth;
gpmd->curfalloff = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curfalloff) {
- BKE_curvemapping_initialize(gpmd->curfalloff);
+ BKE_curvemapping_init(gpmd->curfalloff);
}
}
@@ -120,7 +120,7 @@ static float gpencil_hook_falloff(const struct GPHookData_cb *tData, const float
if (len_sq > tData->falloff_sq) {
return 0.0f;
}
- else if (len_sq > 0.0f) {
+ if (len_sq > 0.0f) {
float fac;
if (tData->falloff_type == eGPHook_Falloff_Const) {
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
index 0d8a5f7914e..67c26bf2584 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c
@@ -79,7 +79,7 @@ static void initData(GpencilModifierData *md)
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
BKE_curvemap_reset(curve->cm, &curve->clipr, CURVE_PRESET_BELL, CURVEMAP_SLOPE_POSITIVE);
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
index 9cc3712e8f4..75f929e979e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c
@@ -105,19 +105,23 @@ static void deformStroke(GpencilModifierData *md,
bGPDspoint *pt = &gps->points[i];
MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL;
- /* verify vertex group */
+ /* Verify vertex group. */
const float weight = get_modifier_point_weight(
dvert, (mmd->flag & GP_OFFSET_INVERT_VGROUP) != 0, def_nr);
if (weight < 0.0f) {
continue;
}
- /* calculate matrix */
+ /* Calculate matrix. */
mul_v3_v3fl(loc, mmd->loc, weight);
mul_v3_v3fl(rot, mmd->rot, weight);
mul_v3_v3fl(scale, mmd->scale, weight);
add_v3_fl(scale, 1.0);
loc_eul_size_to_mat4(mat, loc, rot, scale);
+ /* Apply scale to thickness. */
+ float unit_scale = (scale[0] + scale[1] + scale[2]) / 3.0f;
+ pt->pressure *= unit_scale;
+
mul_m4_v3(mat, &pt->x);
}
/* Calc geometry data. */
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
index 34142709c18..efa58cc4ae0 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c
@@ -70,7 +70,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
index 557a305d731..e3511d9645e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
@@ -66,7 +66,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
index 4fa47a592ba..68547614776 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c
@@ -65,7 +65,7 @@ static void initData(GpencilModifierData *md)
gpmd->material = NULL;
gpmd->curve_thickness = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_thickness) {
- BKE_curvemapping_initialize(gpmd->curve_thickness);
+ BKE_curvemapping_init(gpmd->curve_thickness);
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
index 315f1b9e19b..389f3ca1bd2 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c
@@ -169,7 +169,7 @@ static int remapTime(struct GpencilModifierData *md,
const int delta = abs(sfra - nfra);
return efra - delta + 1;
}
- else if (cfra + offset > efra) {
+ if (cfra + offset > efra) {
return nfra - efra + sfra - 1;
}
}
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
index da7d33839f1..9d10fcbe49b 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c
@@ -96,7 +96,7 @@ static void initData(GpencilModifierData *md)
gpmd->curve_intensity = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
if (gpmd->curve_intensity) {
CurveMapping *curve = gpmd->curve_intensity;
- BKE_curvemapping_initialize(curve);
+ BKE_curvemapping_init(curve);
}
}
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 4f90482d16e..3ea18f72166 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -52,38 +52,37 @@ set(INC_SYS
)
set(SRC
- intern/gpu_attr_binding.c
- intern/gpu_batch.c
+ intern/gpu_attr_binding.cc
+ intern/gpu_batch.cc
intern/gpu_batch_presets.c
intern/gpu_batch_utils.c
intern/gpu_buffers.c
intern/gpu_codegen.c
- intern/gpu_context.cpp
- intern/gpu_debug.c
- intern/gpu_draw.c
- intern/gpu_draw_smoke.c
- intern/gpu_element.c
- intern/gpu_extensions.c
- intern/gpu_framebuffer.c
- intern/gpu_immediate.c
+ intern/gpu_context.cc
+ intern/gpu_debug.cc
+ intern/gpu_element.cc
+ intern/gpu_extensions.cc
+ intern/gpu_framebuffer.cc
+ intern/gpu_immediate.cc
intern/gpu_immediate_util.c
intern/gpu_init_exit.c
intern/gpu_material.c
intern/gpu_material_library.c
- intern/gpu_matrix.c
+ intern/gpu_matrix.cc
intern/gpu_node_graph.c
- intern/gpu_platform.c
+ intern/gpu_platform.cc
intern/gpu_primitive.c
intern/gpu_select.c
intern/gpu_select_pick.c
intern/gpu_select_sample_query.c
- intern/gpu_shader.c
- intern/gpu_shader_interface.c
- intern/gpu_state.c
- intern/gpu_texture.c
- intern/gpu_uniformbuffer.c
- intern/gpu_vertex_buffer.c
- intern/gpu_vertex_format.c
+ intern/gpu_shader.cc
+ intern/gpu_shader_builtin.c
+ intern/gpu_shader_interface.cc
+ intern/gpu_state.cc
+ intern/gpu_texture.cc
+ intern/gpu_uniformbuffer.cc
+ intern/gpu_vertex_buffer.cc
+ intern/gpu_vertex_format.cc
intern/gpu_viewport.c
GPU_attr_binding.h
@@ -94,7 +93,6 @@ set(SRC
GPU_common.h
GPU_context.h
GPU_debug.h
- GPU_draw.h
GPU_element.h
GPU_extensions.h
GPU_framebuffer.h
@@ -216,6 +214,8 @@ data_to_c_simple(shaders/gpu_shader_text_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_keyframe_diamond_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_keyframe_diamond_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_codegen_lib.glsl SRC)
+
data_to_c_simple(shaders/gpu_shader_geometry.glsl SRC)
data_to_c_simple(shaders/material/gpu_shader_material_add_shader.glsl SRC)
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index ca6aaa90ddc..71a29d0b178 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -126,9 +126,8 @@ int GPU_batch_vertbuf_add_ex(GPUBatch *, GPUVertBuf *, bool own_vbo);
#define GPU_batch_vertbuf_add(batch, verts) GPU_batch_vertbuf_add_ex(batch, verts, false)
-void GPU_batch_program_set_no_use(GPUBatch *, uint32_t program, const GPUShaderInterface *);
-void GPU_batch_program_set(GPUBatch *, uint32_t program, const GPUShaderInterface *);
-void GPU_batch_program_set_shader(GPUBatch *, GPUShader *shader);
+void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader);
+void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader);
void GPU_batch_program_set_imm_shader(GPUBatch *batch);
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id);
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
diff --git a/source/blender/gpu/GPU_debug.h b/source/blender/gpu/GPU_debug.h
index 282c2437640..be822056678 100644
--- a/source/blender/gpu/GPU_debug.h
+++ b/source/blender/gpu/GPU_debug.h
@@ -23,8 +23,6 @@
#pragma once
-#include "GPU_glew.h"
-
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h
deleted file mode 100644
index c0458fec7c3..00000000000
--- a/source/blender/gpu/GPU_draw.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- */
-
-#pragma once
-
-#include "BLI_utildefines.h"
-#include "DNA_object_enums.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct FluidModifierData;
-struct ImBuf;
-struct Image;
-struct ImageUser;
-struct Main;
-
-/* OpenGL drawing functions related to shading. */
-
-/* Mipmap settings
- * - these will free textures on changes */
-
-void GPU_set_mipmap(struct Main *bmain, bool mipmap);
-bool GPU_get_mipmap(void);
-void GPU_set_linear_mipmap(bool linear);
-bool GPU_get_linear_mipmap(void);
-void GPU_paint_set_mipmap(struct Main *bmain, bool mipmap);
-
-/* Anisotropic filtering settings
- * - these will free textures on changes */
-void GPU_set_anisotropic(float value);
-float GPU_get_anisotropic(void);
-
-/* Image updates and free
- * - these deal with images bound as opengl textures */
-
-void GPU_paint_update_image(
- struct Image *ima, struct ImageUser *iuser, int x, int y, int w, int h);
-void GPU_create_gl_tex(unsigned int *bind,
- unsigned int *rect,
- float *frect,
- int rectw,
- int recth,
- int textarget,
- bool mipmap,
- bool half_float,
- bool use_srgb,
- struct Image *ima);
-void GPU_create_gl_tex_compressed(unsigned int *bind,
- int textarget,
- struct Image *ima,
- struct ImBuf *ibuf);
-bool GPU_upload_dxt_texture(struct ImBuf *ibuf, bool use_srgb);
-void GPU_free_image(struct Image *ima);
-void GPU_free_images(struct Main *bmain);
-void GPU_free_images_anim(struct Main *bmain);
-void GPU_free_images_old(struct Main *bmain);
-
-/* gpu_draw_smoke.c */
-void GPU_free_smoke(struct FluidModifierData *fmd);
-void GPU_free_smoke_velocity(struct FluidModifierData *fmd);
-void GPU_create_smoke(struct FluidModifierData *fmd, int highres);
-void GPU_create_smoke_coba_field(struct FluidModifierData *fmd);
-void GPU_create_smoke_velocity(struct FluidModifierData *fmd);
-
-/* Delayed free of OpenGL buffers by main thread */
-void GPU_free_unused_buffers(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 6cb7a297d09..2ce6e458378 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -51,6 +51,8 @@ bool GPU_use_main_context_workaround(void);
bool GPU_texture_copy_workaround(void);
bool GPU_crappy_amd_driver(void);
+int GPU_texture_size_with_limit(int res);
+
bool GPU_mem_stats_supported(void);
void GPU_mem_stats_get(int *totalmem, int *freemem);
diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index 4958d1eaac8..9dc07fefd4e 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -31,7 +31,7 @@ extern "C" {
typedef struct GPUAttachment {
struct GPUTexture *tex;
- int mip, layer;
+ int layer, mip;
} GPUAttachment;
typedef enum eGPUFrameBufferBits {
@@ -119,35 +119,35 @@ void GPU_framebuffer_config_array(GPUFrameBuffer *fb, const GPUAttachment *confi
#define GPU_ATTACHMENT_NONE \
{ \
- .tex = NULL, .layer = -1, .mip = 0, \
+ NULL, -1, 0, \
}
#define GPU_ATTACHMENT_LEAVE \
{ \
- .tex = NULL, .layer = -1, .mip = -1, \
+ NULL, -1, -1, \
}
#define GPU_ATTACHMENT_TEXTURE(_tex) \
{ \
- .tex = _tex, .layer = -1, .mip = 0, \
+ _tex, -1, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_MIP(_tex, _mip) \
{ \
- .tex = _tex, .layer = -1, .mip = _mip, \
+ _tex, -1, _mip, \
}
#define GPU_ATTACHMENT_TEXTURE_LAYER(_tex, _layer) \
{ \
- .tex = _tex, .layer = _layer, .mip = 0, \
+ _tex, _layer, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_LAYER_MIP(_tex, _layer, _mip) \
{ \
- .tex = _tex, .layer = _layer, .mip = _mip, \
+ _tex, _layer, _mip, \
}
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE(_tex, _face) \
{ \
- .tex = _tex, .layer = _face, .mip = 0, \
+ _tex, _face, 0, \
}
#define GPU_ATTACHMENT_TEXTURE_CUBEFACE_MIP(_tex, _face, _mip) \
{ \
- .tex = _tex, .layer = _face, .mip = _mip, \
+ _tex, _face, _mip, \
}
/* Framebuffer operations */
@@ -211,7 +211,7 @@ GPUOffScreen *GPU_offscreen_create(
void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save);
void GPU_offscreen_unbind(GPUOffScreen *ofs, bool restore);
-void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels);
void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y);
int GPU_offscreen_width(const GPUOffScreen *ofs);
int GPU_offscreen_height(const GPUOffScreen *ofs);
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index 08bfcb95942..41d4f5d28d3 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -41,7 +41,7 @@ extern "C" {
GPUVertFormat *immVertexFormat(void);
/** Every immBegin must have a program bound first. */
-void immBindProgram(uint32_t program, const GPUShaderInterface *);
+void immBindShader(GPUShader *shader);
/** Call after your last immEnd, or before binding another program. */
void immUnbindProgram(void);
@@ -133,7 +133,7 @@ void immUniformColor3ubvAlpha(const unsigned char rgb[3], unsigned char a);
void immUniformColor4ubv(const unsigned char rgba[4]);
/**
- * Extend #immBindProgram to use Blender’s library of built-in shader programs.
+ * Extend #immBindShader to use Blender’s library of built-in shader programs.
* Use #immUnbindProgram() when done.
*/
void immBindBuiltinProgram(eGPUBuiltinShader shader_id);
diff --git a/source/blender/gpu/GPU_init_exit.h b/source/blender/gpu/GPU_init_exit.h
index bd4771e2357..42c56940c4c 100644
--- a/source/blender/gpu/GPU_init_exit.h
+++ b/source/blender/gpu/GPU_init_exit.h
@@ -31,7 +31,7 @@ extern "C" {
void GPU_init(void);
void GPU_exit(void);
-bool GPU_is_initialized(void);
+bool GPU_is_init(void);
#ifdef __cplusplus
}
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index b2352b3f3b0..b8957ff1819 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -109,6 +109,7 @@ typedef enum eGPUMatFlag {
GPU_MATFLAG_GLOSSY = (1 << 1),
GPU_MATFLAG_REFRACT = (1 << 2),
GPU_MATFLAG_SSS = (1 << 3),
+ GPU_MATFLAG_BARYCENTRIC = (1 << 4),
} eGPUMatFlag;
typedef enum eGPUBlendMode {
@@ -136,6 +137,13 @@ typedef enum eGPUMaterialStatus {
GPU_MAT_SUCCESS,
} eGPUMaterialStatus;
+typedef void (*GPUMaterialEvalCallbackFn)(GPUMaterial *mat,
+ int options,
+ const char **vert_code,
+ const char **geom_code,
+ const char **frag_lib,
+ const char **defines);
+
GPUNodeLink *GPU_constant(const float *num);
GPUNodeLink *GPU_uniform(const float *num);
GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name);
@@ -189,7 +197,8 @@ GPUMaterial *GPU_material_from_nodetree(struct Scene *scene,
const char *geom_code,
const char *frag_lib,
const char *defines,
- const char *name);
+ const char *name,
+ GPUMaterialEvalCallbackFn callback);
void GPU_material_compile(GPUMaterial *mat);
void GPU_material_free(struct ListBase *gpumaterial);
diff --git a/source/blender/gpu/GPU_platform.h b/source/blender/gpu/GPU_platform.h
index 0848252c788..a89298c0d01 100644
--- a/source/blender/gpu/GPU_platform.h
+++ b/source/blender/gpu/GPU_platform.h
@@ -24,10 +24,7 @@
#pragma once
#include "BLI_sys_types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "BLI_utildefines.h"
/* GPU platform support */
@@ -42,6 +39,8 @@ typedef enum eGPUDeviceType {
GPU_DEVICE_ANY = (0xff),
} eGPUDeviceType;
+ENUM_OPERATORS(eGPUDeviceType)
+
typedef enum eGPUOSType {
GPU_OS_WIN = (1 << 8),
GPU_OS_MAC = (1 << 9),
@@ -62,6 +61,10 @@ typedef enum eGPUSupportLevel {
GPU_SUPPORT_LEVEL_UNSUPPORTED,
} eGPUSupportLevel;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool GPU_type_matches(eGPUDeviceType device, eGPUOSType os, eGPUDriverType driver);
eGPUSupportLevel GPU_platform_support_level(void);
const char *GPU_platform_support_level_key(void);
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 1ec70c1106b..f782742ae53 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -86,8 +86,6 @@ void GPU_shader_transform_feedback_disable(GPUShader *shader);
int GPU_shader_get_program(GPUShader *shader);
-void *GPU_shader_get_interface(GPUShader *shader);
-
void GPU_shader_set_srgb_uniform(const struct GPUShaderInterface *interface);
int GPU_shader_get_uniform(GPUShader *shader, const char *name);
diff --git a/source/blender/gpu/GPU_state.h b/source/blender/gpu/GPU_state.h
index 4cf1d9844ae..4a2c90e241b 100644
--- a/source/blender/gpu/GPU_state.h
+++ b/source/blender/gpu/GPU_state.h
@@ -86,6 +86,7 @@ bool GPU_depth_mask_get(void);
void GPU_stencil_mask(uint stencil);
void GPU_unpack_row_length_set(uint len);
void GPU_clip_distances(int enabled_len);
+bool GPU_mipmap_enabled(void);
void GPU_flush(void);
void GPU_finish(void);
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index 7cbd4b1eee3..7ee7f8fcdec 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -24,6 +24,7 @@
#pragma once
#include "BLI_utildefines.h"
+
#include "GPU_state.h"
struct GPUVertBuf;
@@ -42,7 +43,6 @@ typedef struct GPUTexture GPUTexture;
* - Internally used by textures.
* - All states are created at startup to avoid runtime costs.
*/
-
typedef enum eGPUSamplerState {
GPU_SAMPLER_FILTER = (1 << 0),
GPU_SAMPLER_MIPMAP = (1 << 1),
@@ -56,6 +56,8 @@ typedef enum eGPUSamplerState {
GPU_SAMPLER_MAX = (1 << 8),
} eGPUSamplerState;
+ENUM_OPERATORS(eGPUSamplerState)
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -120,7 +122,6 @@ typedef enum eGPUTextureFormat {
#if 0
GPU_RGB10_A2,
GPU_RGB10_A2UI,
- GPU_SRGB8_A8,
#endif
GPU_R11F_G11F_B10F,
GPU_DEPTH32F_STENCIL8,
@@ -149,7 +150,13 @@ typedef enum eGPUTextureFormat {
GPU_R8_SNORM,
#endif
-/* Special formats texture only */
+ /* Special formats texture only */
+ GPU_SRGB8_A8_DXT1,
+ GPU_SRGB8_A8_DXT3,
+ GPU_SRGB8_A8_DXT5,
+ GPU_RGBA8_DXT1,
+ GPU_RGBA8_DXT3,
+ GPU_RGBA8_DXT5,
#if 0
GPU_SRGB8,
GPU_RGB9_E5,
@@ -222,17 +229,10 @@ GPUTexture *GPU_texture_create_cube_array(
GPUTexture *GPU_texture_create_from_vertbuf(struct GPUVertBuf *vert);
GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat data_type, const uint buffer);
-GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode);
-GPUTexture *GPU_texture_from_blender(struct Image *ima,
- struct ImageUser *iuser,
- struct ImBuf *ibuf,
- int textarget);
+GPUTexture *GPU_texture_create_compressed(
+ int w, int h, int miplen, eGPUTextureFormat format, const void *data);
-/* movie clip drawing */
-GPUTexture *GPU_texture_from_movieclip(struct MovieClip *clip,
- struct MovieClipUser *cuser,
- int textarget);
-void GPU_free_texture_movieclip(struct MovieClip *clip);
+GPUTexture *GPU_texture_create_error(int dimension, bool array);
void GPU_texture_add_mipmap(GPUTexture *tex,
eGPUDataFormat gpu_data_format,
@@ -268,6 +268,7 @@ void GPU_texture_unbind_all(void);
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src);
void GPU_texture_generate_mipmap(GPUTexture *tex);
+void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso);
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare);
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter);
void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter);
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
index 56e258d8a48..e2b2a757fb9 100644
--- a/source/blender/gpu/GPU_uniformbuffer.h
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -41,8 +41,7 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_);
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number);
void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo);
-
-int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo);
+void GPU_uniformbuffer_unbind_all(void);
bool GPU_uniformbuffer_is_empty(GPUUniformBuffer *ubo);
bool GPU_uniformbuffer_is_dirty(GPUUniformBuffer *ubo);
diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h
index 8f194ed2c36..757255496e0 100644
--- a/source/blender/gpu/GPU_vertex_buffer.h
+++ b/source/blender/gpu/GPU_vertex_buffer.h
@@ -58,10 +58,10 @@ typedef struct GPUVertBuf {
/** 0 indicates not yet allocated. */
uint32_t vbo_id;
/** Usage hint for GL optimisation. */
- uint usage : 2;
+ GPUUsageType usage;
/** Data has been touched and need to be reuploaded to GPU. */
- uint dirty : 1;
- unsigned char *data; /* NULL indicates data in VRAM (unmapped) */
+ bool dirty;
+ uchar *data; /* NULL indicates data in VRAM (unmapped) */
} GPUVertBuf;
GPUVertBuf *GPU_vertbuf_create(GPUUsageType);
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 391eaf61876..59af912ed3d 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -41,7 +41,7 @@ extern "C" {
#define GPU_MAX_SAFE_ATTR_NAME 12
typedef enum {
- GPU_COMP_I8,
+ GPU_COMP_I8 = 0,
GPU_COMP_U8,
GPU_COMP_I16,
GPU_COMP_U16,
@@ -51,17 +51,21 @@ typedef enum {
GPU_COMP_F32,
GPU_COMP_I10,
+ /* Warning! adjust GPUVertAttr if changing. */
} GPUVertCompType;
typedef enum {
- GPU_FETCH_FLOAT,
+ GPU_FETCH_FLOAT = 0,
GPU_FETCH_INT,
GPU_FETCH_INT_TO_FLOAT_UNIT, /* 127 (ubyte) -> 0.5 (and so on for other int types) */
GPU_FETCH_INT_TO_FLOAT, /* 127 (any int type) -> 127.0 */
+ /* Warning! adjust GPUVertAttr if changing. */
} GPUVertFetchMode;
typedef struct GPUVertAttr {
+ /* GPUVertFetchMode */
uint fetch_mode : 2;
+ /* GPUVertCompType */
uint comp_type : 3;
/* 1 to 4 or 8 or 12 or 16 */
uint comp_len : 5;
@@ -71,8 +75,6 @@ typedef struct GPUVertAttr {
uint offset : 11;
/* up to GPU_VERT_ATTR_MAX_NAMES */
uint name_len : 3;
- uint gl_comp_type;
- /* -- 8 Bytes -- */
uchar names[GPU_VERT_ATTR_MAX_NAMES];
} GPUVertAttr;
diff --git a/source/blender/gpu/intern/gpu_attr_binding.c b/source/blender/gpu/intern/gpu_attr_binding.cc
index 6cb60884620..6cb60884620 100644
--- a/source/blender/gpu/intern/gpu_attr_binding.c
+++ b/source/blender/gpu/intern/gpu_attr_binding.cc
diff --git a/source/blender/gpu/intern/gpu_attr_binding_private.h b/source/blender/gpu/intern/gpu_attr_binding_private.h
index 4f18655ec62..4d359343c38 100644
--- a/source/blender/gpu/intern/gpu_attr_binding_private.h
+++ b/source/blender/gpu/intern/gpu_attr_binding_private.h
@@ -28,9 +28,18 @@
#include "GPU_shader_interface.h"
#include "GPU_vertex_format.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO(fclem) remove, use shaderface directly. */
void AttrBinding_clear(GPUAttrBinding *binding);
void get_attr_locations(const GPUVertFormat *format,
GPUAttrBinding *binding,
const GPUShaderInterface *shaderface);
uint read_attr_location(const GPUAttrBinding *binding, uint a_idx);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.cc
index 5f77f13c135..9f9adcacfa6 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.cc
@@ -37,6 +37,7 @@
#include "gpu_context_private.h"
#include "gpu_primitive_private.h"
#include "gpu_shader_private.h"
+#include "gpu_vertex_format_private.h"
#include <limits.h>
#include <stdlib.h>
@@ -89,7 +90,7 @@ GPUBatch *GPU_batch_create_ex(GPUPrimType prim_type,
GPUIndexBuf *elem,
uint owns_flag)
{
- GPUBatch *batch = MEM_callocN(sizeof(GPUBatch), "GPUBatch");
+ GPUBatch *batch = (GPUBatch *)MEM_callocN(sizeof(GPUBatch), "GPUBatch");
GPU_batch_init_ex(batch, prim_type, verts, elem, owns_flag);
return batch;
}
@@ -327,10 +328,10 @@ static GLuint batch_vao_get(GPUBatch *batch)
}
/* Init dynamic arrays and let the branch below set the values. */
batch->dynamic_vaos.count = GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- batch->dynamic_vaos.interfaces = MEM_callocN(
+ batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_callocN(
batch->dynamic_vaos.count * sizeof(GPUShaderInterface *), "dyn vaos interfaces");
- batch->dynamic_vaos.vao_ids = MEM_callocN(batch->dynamic_vaos.count * sizeof(GLuint),
- "dyn vaos ids");
+ batch->dynamic_vaos.vao_ids = (GLuint *)MEM_callocN(
+ batch->dynamic_vaos.count * sizeof(GLuint), "dyn vaos ids");
}
}
@@ -346,11 +347,11 @@ static GLuint batch_vao_get(GPUBatch *batch)
/* Not enough place, realloc the array. */
i = batch->dynamic_vaos.count;
batch->dynamic_vaos.count += GPU_BATCH_VAO_DYN_ALLOC_COUNT;
- batch->dynamic_vaos.interfaces = MEM_recallocN((void *)batch->dynamic_vaos.interfaces,
- sizeof(GPUShaderInterface *) *
- batch->dynamic_vaos.count);
- batch->dynamic_vaos.vao_ids = MEM_recallocN(batch->dynamic_vaos.vao_ids,
- sizeof(GLuint) * batch->dynamic_vaos.count);
+ batch->dynamic_vaos.interfaces = (const GPUShaderInterface **)MEM_recallocN(
+ (void *)batch->dynamic_vaos.interfaces,
+ sizeof(GPUShaderInterface *) * batch->dynamic_vaos.count);
+ batch->dynamic_vaos.vao_ids = (GLuint *)MEM_recallocN(
+ batch->dynamic_vaos.vao_ids, sizeof(GLuint) * batch->dynamic_vaos.count);
}
batch->dynamic_vaos.interfaces[i] = batch->interface;
batch->dynamic_vaos.vao_ids[i] = new_vao = GPU_vao_alloc();
@@ -370,22 +371,20 @@ static GLuint batch_vao_get(GPUBatch *batch)
return new_vao;
}
-void GPU_batch_program_set_no_use(GPUBatch *batch,
- uint32_t program,
- const GPUShaderInterface *shaderface)
+void GPU_batch_set_shader_no_bind(GPUBatch *batch, GPUShader *shader)
{
#if TRUST_NO_ONE
- assert(glIsProgram(program));
+ assert(glIsProgram(shader->program));
assert(batch->program_in_use == 0);
#endif
- batch->interface = shaderface;
- batch->program = program;
+ batch->interface = shader->interface;
+ batch->program = shader->program;
batch->vao_id = batch_vao_get(batch);
}
-void GPU_batch_program_set(GPUBatch *batch, uint32_t program, const GPUShaderInterface *shaderface)
+void GPU_batch_set_shader(GPUBatch *batch, GPUShader *shader)
{
- GPU_batch_program_set_no_use(batch, program, shaderface);
+ GPU_batch_set_shader_no_bind(batch, shader);
GPU_batch_program_use_begin(batch); /* hack! to make Batch_Uniform* simpler */
}
@@ -440,6 +439,7 @@ static void create_bindings(GPUVertBuf *verts,
}
const GLvoid *pointer = (const GLubyte *)0 + offset + v_first * stride;
+ const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type));
for (uint n_idx = 0; n_idx < a->name_len; n_idx++) {
const char *name = GPU_vertformat_attr_name_get(format, a, n_idx);
@@ -452,19 +452,13 @@ static void create_bindings(GPUVertBuf *verts,
*attr_mask &= ~(1 << input->location);
if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) {
-#if TRUST_NO_ONE
- assert(a->fetch_mode == GPU_FETCH_FLOAT);
- assert(a->gl_comp_type == GL_FLOAT);
-#endif
+ BLI_assert(a->fetch_mode == GPU_FETCH_FLOAT);
+ BLI_assert(a->comp_type == GPU_COMP_F32);
for (int i = 0; i < a->comp_len / 4; i++) {
glEnableVertexAttribArray(input->location + i);
glVertexAttribDivisor(input->location + i, (use_instancing) ? 1 : 0);
- glVertexAttribPointer(input->location + i,
- 4,
- a->gl_comp_type,
- GL_FALSE,
- stride,
- (const GLubyte *)pointer + i * 16);
+ glVertexAttribPointer(
+ input->location + i, 4, type, GL_FALSE, stride, (const GLubyte *)pointer + i * 16);
}
}
else {
@@ -474,15 +468,13 @@ static void create_bindings(GPUVertBuf *verts,
switch (a->fetch_mode) {
case GPU_FETCH_FLOAT:
case GPU_FETCH_INT_TO_FLOAT:
- glVertexAttribPointer(
- input->location, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer);
+ glVertexAttribPointer(input->location, a->comp_len, type, GL_FALSE, stride, pointer);
break;
case GPU_FETCH_INT_TO_FLOAT_UNIT:
- glVertexAttribPointer(
- input->location, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer);
+ glVertexAttribPointer(input->location, a->comp_len, type, GL_TRUE, stride, pointer);
break;
case GPU_FETCH_INT:
- glVertexAttribIPointer(input->location, a->comp_len, a->gl_comp_type, stride, pointer);
+ glVertexAttribIPointer(input->location, a->comp_len, type, stride, pointer);
break;
}
}
@@ -839,7 +831,7 @@ struct GPUDrawList {
GPUDrawList *GPU_draw_list_create(int length)
{
- GPUDrawList *list = MEM_callocN(sizeof(GPUDrawList), "GPUDrawList");
+ GPUDrawList *list = (GPUDrawList *)MEM_callocN(sizeof(GPUDrawList), "GPUDrawList");
/* Alloc the biggest possible command list which is indexed. */
list->buffer_size = sizeof(GPUDrawCommandIndexed) * length;
if (USE_MULTI_DRAW_INDIRECT) {
@@ -848,7 +840,7 @@ GPUDrawList *GPU_draw_list_create(int length)
glBufferData(GL_DRAW_INDIRECT_BUFFER, list->buffer_size, NULL, GL_DYNAMIC_DRAW);
}
else {
- list->commands = MEM_mallocN(list->buffer_size, "GPUDrawList data");
+ list->commands = (GPUDrawCommand *)MEM_mallocN(list->buffer_size, "GPUDrawList data");
}
return list;
}
@@ -880,7 +872,7 @@ void GPU_draw_list_init(GPUDrawList *list, GPUBatch *batch)
list->cmd_offset = 0;
}
GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
- list->commands = glMapBufferRange(
+ list->commands = (GPUDrawCommand *)glMapBufferRange(
GL_DRAW_INDIRECT_BUFFER, list->cmd_offset, list->buffer_size - list->cmd_offset, flags);
}
}
@@ -989,17 +981,12 @@ void GPU_draw_list_submit(GPUDrawList *list)
/** \name Utilities
* \{ */
-void GPU_batch_program_set_shader(GPUBatch *batch, GPUShader *shader)
-{
- GPU_batch_program_set(batch, shader->program, shader->interface);
-}
-
void GPU_batch_program_set_builtin_with_config(GPUBatch *batch,
eGPUBuiltinShader shader_id,
eGPUShaderConfig sh_cfg)
{
GPUShader *shader = GPU_shader_get_builtin_shader_with_config(shader_id, sh_cfg);
- GPU_batch_program_set(batch, shader->program, shader->interface);
+ GPU_batch_set_shader(batch, shader);
}
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
@@ -1012,10 +999,7 @@ void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
* DO NOT DRAW WITH THE BATCH BEFORE CALLING immUnbindProgram. */
void GPU_batch_program_set_imm_shader(GPUBatch *batch)
{
- GLuint program;
- GPUShaderInterface *interface;
- immGetProgram(&program, &interface);
- GPU_batch_program_set(batch, program, interface);
+ GPU_batch_set_shader(batch, immGetShader());
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_batch_presets.c b/source/blender/gpu/intern/gpu_batch_presets.c
index 7f842d4d508..3d9b4326c7e 100644
--- a/source/blender/gpu/intern/gpu_batch_presets.c
+++ b/source/blender/gpu/intern/gpu_batch_presets.c
@@ -129,12 +129,11 @@ GPUBatch *GPU_batch_preset_sphere(int lod)
if (lod == 0) {
return g_presets_3d.batch.sphere_low;
}
- else if (lod == 1) {
+ if (lod == 1) {
return g_presets_3d.batch.sphere_med;
}
- else {
- return g_presets_3d.batch.sphere_high;
- }
+
+ return g_presets_3d.batch.sphere_high;
}
GPUBatch *GPU_batch_preset_sphere_wire(int lod)
@@ -145,9 +144,8 @@ GPUBatch *GPU_batch_preset_sphere_wire(int lod)
if (lod == 0) {
return g_presets_3d.batch.sphere_wire_low;
}
- else {
- return g_presets_3d.batch.sphere_wire_med;
- }
+
+ return g_presets_3d.batch.sphere_wire_med;
}
/** \} */
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 10d5a860f6a..d32b45e0b5f 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -695,7 +695,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
}
if (show_vcol) {
- ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
+ const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &vcol);
}
@@ -749,7 +749,7 @@ void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers,
empty_mask = empty_mask && (cmask == 0);
}
- ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
+ const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &vcol);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &vcol);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &vcol);
@@ -832,12 +832,12 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
}
if (show_vcol) {
- ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
+ const ushort vcol[4] = {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX};
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, v_index, &vcol);
}
/* Add default face sets color to avoid artifacts. */
- uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
+ const uchar face_set[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.fset, v_index, &face_set);
}
@@ -1083,9 +1083,8 @@ GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool
if (wires) {
return (fast && buffers->lines_fast) ? buffers->lines_fast : buffers->lines;
}
- else {
- return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles;
- }
+
+ return (fast && buffers->triangles_fast) ? buffers->triangles_fast : buffers->triangles;
}
bool GPU_pbvh_buffers_has_overlays(GPU_PBVH_Buffers *buffers)
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 155179205c5..08d2779043e 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -41,7 +41,6 @@
#include "BKE_material.h"
#include "GPU_extensions.h"
-#include "GPU_glew.h"
#include "GPU_material.h"
#include "GPU_shader.h"
#include "GPU_uniformbuffer.h"
@@ -56,8 +55,8 @@
#include <stdarg.h>
#include <string.h>
+extern char datatoc_gpu_shader_codegen_lib_glsl[];
extern char datatoc_gpu_shader_common_obinfos_lib_glsl[];
-extern char datatoc_common_view_lib_glsl[];
/* -------------------- GPUPass Cache ------------------ */
/**
@@ -221,79 +220,74 @@ static const char *gpu_builtin_name(eGPUBuiltin builtin)
if (builtin == GPU_VIEW_MATRIX) {
return "unfviewmat";
}
- else if (builtin == GPU_OBJECT_MATRIX) {
+ if (builtin == GPU_OBJECT_MATRIX) {
return "unfobmat";
}
- else if (builtin == GPU_INVERSE_VIEW_MATRIX) {
+ if (builtin == GPU_INVERSE_VIEW_MATRIX) {
return "unfinvviewmat";
}
- else if (builtin == GPU_INVERSE_OBJECT_MATRIX) {
+ if (builtin == GPU_INVERSE_OBJECT_MATRIX) {
return "unfinvobmat";
}
- else if (builtin == GPU_LOC_TO_VIEW_MATRIX) {
+ if (builtin == GPU_LOC_TO_VIEW_MATRIX) {
return "unflocaltoviewmat";
}
- else if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
+ if (builtin == GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
return "unfinvlocaltoviewmat";
}
- else if (builtin == GPU_VIEW_POSITION) {
+ if (builtin == GPU_VIEW_POSITION) {
return "varposition";
}
- else if (builtin == GPU_WORLD_NORMAL) {
+ if (builtin == GPU_WORLD_NORMAL) {
return "varwnormal";
}
- else if (builtin == GPU_VIEW_NORMAL) {
+ if (builtin == GPU_VIEW_NORMAL) {
return "varnormal";
}
- else if (builtin == GPU_OBJECT_COLOR) {
+ if (builtin == GPU_OBJECT_COLOR) {
return "unfobjectcolor";
}
- else if (builtin == GPU_AUTO_BUMPSCALE) {
+ if (builtin == GPU_AUTO_BUMPSCALE) {
return "unfobautobumpscale";
}
- else if (builtin == GPU_CAMERA_TEXCO_FACTORS) {
+ if (builtin == GPU_CAMERA_TEXCO_FACTORS) {
return "unfcameratexfactors";
}
- else if (builtin == GPU_PARTICLE_SCALAR_PROPS) {
+ if (builtin == GPU_PARTICLE_SCALAR_PROPS) {
return "unfparticlescalarprops";
}
- else if (builtin == GPU_PARTICLE_LOCATION) {
+ if (builtin == GPU_PARTICLE_LOCATION) {
return "unfparticleco";
}
- else if (builtin == GPU_PARTICLE_VELOCITY) {
+ if (builtin == GPU_PARTICLE_VELOCITY) {
return "unfparticlevel";
}
- else if (builtin == GPU_PARTICLE_ANG_VELOCITY) {
+ if (builtin == GPU_PARTICLE_ANG_VELOCITY) {
return "unfparticleangvel";
}
- else if (builtin == GPU_OBJECT_INFO) {
+ if (builtin == GPU_OBJECT_INFO) {
return "unfobjectinfo";
}
- else if (builtin == GPU_BARYCENTRIC_TEXCO) {
+ if (builtin == GPU_BARYCENTRIC_TEXCO) {
return "unfbarycentrictex";
}
- else if (builtin == GPU_BARYCENTRIC_DIST) {
+ if (builtin == GPU_BARYCENTRIC_DIST) {
return "unfbarycentricdist";
}
- else {
- return "";
- }
+ return "";
}
static void codegen_set_unique_ids(GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUInput *input;
- GPUOutput *output;
int id = 1;
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
/* set id for unique names of uniform variables */
input->id = id++;
}
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
/* set id for unique names of tmp variables storing output */
output->id = id++;
}
@@ -307,17 +301,10 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
DynStr *ds,
GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUInput *input;
const char *name;
int builtins = 0;
ListBase ubo_inputs = {NULL, NULL};
- /* Attributes */
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- BLI_dynstr_appendf(ds, "in %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
- }
-
/* Textures */
LISTBASE_FOREACH (GPUMaterialTexture *, tex, &graph->textures) {
if (tex->colorband) {
@@ -339,8 +326,9 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
}
/* Print other uniforms */
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
+
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
if (input->source == GPU_SOURCE_BUILTIN) {
/* only define each builtin uniform/varying once */
if (!(builtins & input->builtin)) {
@@ -382,8 +370,8 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
BLI_dynstr_appendf(ds, "\nlayout (std140) uniform %s {\n", GPU_UBO_BLOCK_NAME);
LISTBASE_FOREACH (LinkData *, link, &ubo_inputs) {
- input = link->data;
- BLI_dynstr_appendf(ds, "\t%s unf%d;\n", gpu_data_type_to_string(input->type), input->id);
+ GPUInput *input = (GPUInput *)(link->data);
+ BLI_dynstr_appendf(ds, " %s unf%d;\n", gpu_data_type_to_string(input->type), input->id);
}
BLI_dynstr_append(ds, "};\n");
BLI_freelistN(&ubo_inputs);
@@ -396,34 +384,26 @@ static int codegen_process_uniforms_functions(GPUMaterial *material,
static void codegen_declare_tmps(DynStr *ds, GPUNodeGraph *graph)
{
- GPUNode *node;
- GPUOutput *output;
-
- for (node = graph->nodes.first; node; node = node->next) {
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
/* declare temporary variables for node output storage */
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
if (output->type == GPU_CLOSURE) {
- BLI_dynstr_appendf(ds, "\tClosure tmp%d;\n", output->id);
+ BLI_dynstr_appendf(ds, " Closure tmp%d;\n", output->id);
}
else {
- BLI_dynstr_appendf(ds, "\t%s tmp%d;\n", gpu_data_type_to_string(output->type), output->id);
+ BLI_dynstr_appendf(ds, " %s tmp%d;\n", gpu_data_type_to_string(output->type), output->id);
}
}
}
-
BLI_dynstr_append(ds, "\n");
}
static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *finaloutput)
{
- GPUNode *node;
- GPUInput *input;
- GPUOutput *output;
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ BLI_dynstr_appendf(ds, " %s(", node->name);
- for (node = graph->nodes.first; node; node = node->next) {
- BLI_dynstr_appendf(ds, "\t%s(", node->name);
-
- for (input = node->inputs.first; input; input = input->next) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
if (input->source == GPU_SOURCE_TEX) {
BLI_dynstr_append(ds, input->texture->sampler_name);
}
@@ -504,7 +484,7 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f
BLI_dynstr_append(ds, ", ");
}
- for (output = node->outputs.first; output; output = output->next) {
+ LISTBASE_FOREACH (GPUOutput *, output, &node->outputs) {
BLI_dynstr_appendf(ds, "tmp%d", output->id);
if (output->next) {
BLI_dynstr_append(ds, ", ");
@@ -514,21 +494,24 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f
BLI_dynstr_append(ds, ");\n");
}
- BLI_dynstr_appendf(ds, "\n\treturn tmp%d", finaloutput->id);
- BLI_dynstr_append(ds, ";\n");
+ BLI_dynstr_appendf(ds, "\n return tmp%d;\n", finaloutput->id);
}
-static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
+static char *code_generate_fragment(GPUMaterial *material,
+ GPUNodeGraph *graph,
+ const char *interface_str)
{
DynStr *ds = BLI_dynstr_new();
char *code;
int builtins;
-#if 0
- BLI_dynstr_append(ds, FUNCTION_PROTOTYPES);
-#endif
-
codegen_set_unique_ids(graph);
+
+ /* Attributes, Shader stage interface. */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "in codegenInterface {%s};\n\n", interface_str);
+ }
+
builtins = codegen_process_uniforms_functions(material, ds, graph);
if (builtins & (GPU_OBJECT_INFO | GPU_OBJECT_COLOR)) {
@@ -536,73 +519,61 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
}
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "in vec2 barycentricTexCo;\n");
- }
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "flat in vec3 barycentricDist;\n");
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
}
BLI_dynstr_append(ds, "Closure nodetree_exec(void)\n{\n");
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds,
- "\tvec2 barytexco = vec2((fract(barycentricTexCo.y) != 0.0)\n"
- "\t ? barycentricTexCo.x\n"
- "\t : 1.0 - barycentricTexCo.x,\n"
- "\t 0.0);\n");
- BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tvec2 barytexco = barycentricTexCo;\n");
- BLI_dynstr_append(ds, "#endif\n");
+ BLI_dynstr_append(ds, " vec2 barytexco = barycentric_resolve(barycentricTexCo);\n");
}
/* TODO(fclem) get rid of that. */
if (builtins & GPU_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define viewmat ViewMatrix\n");
+ BLI_dynstr_append(ds, " #define viewmat ViewMatrix\n");
}
if (builtins & GPU_CAMERA_TEXCO_FACTORS) {
- BLI_dynstr_append(ds, "\t#define camtexfac CameraTexCoFactors\n");
+ BLI_dynstr_append(ds, " #define camtexfac CameraTexCoFactors\n");
}
if (builtins & GPU_OBJECT_MATRIX) {
- BLI_dynstr_append(ds, "\t#define objmat ModelMatrix\n");
+ BLI_dynstr_append(ds, " #define objmat ModelMatrix\n");
}
if (builtins & GPU_INVERSE_OBJECT_MATRIX) {
- BLI_dynstr_append(ds, "\t#define objinv ModelMatrixInverse\n");
+ BLI_dynstr_append(ds, " #define objinv ModelMatrixInverse\n");
}
if (builtins & GPU_INVERSE_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define viewinv ViewMatrixInverse\n");
+ BLI_dynstr_append(ds, " #define viewinv ViewMatrixInverse\n");
}
if (builtins & GPU_LOC_TO_VIEW_MATRIX) {
- BLI_dynstr_append(ds, "\t#define localtoviewmat (ViewMatrix * ModelMatrix)\n");
+ BLI_dynstr_append(ds, " #define localtoviewmat (ViewMatrix * ModelMatrix)\n");
}
if (builtins & GPU_INVERSE_LOC_TO_VIEW_MATRIX) {
BLI_dynstr_append(ds,
- "\t#define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n");
+ " #define invlocaltoviewmat (ModelMatrixInverse * ViewMatrixInverse)\n");
}
if (builtins & GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tvec3 n;\n");
- BLI_dynstr_append(ds, "\tworld_normals_get(n);\n");
- BLI_dynstr_append(ds, "\tvec3 facingnormal = transform_direction(ViewMatrix, n);\n");
+ BLI_dynstr_append(ds, " vec3 n;\n");
+ BLI_dynstr_append(ds, " world_normals_get(n);\n");
+ BLI_dynstr_append(ds, " vec3 facingnormal = transform_direction(ViewMatrix, n);\n");
BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tvec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n");
+ BLI_dynstr_append(ds, " vec3 facingnormal = gl_FrontFacing ? viewNormal: -viewNormal;\n");
BLI_dynstr_append(ds, "#endif\n");
}
if (builtins & GPU_WORLD_NORMAL) {
- BLI_dynstr_append(ds, "\tvec3 facingwnormal;\n");
+ BLI_dynstr_append(ds, " vec3 facingwnormal;\n");
if (builtins & GPU_VIEW_NORMAL) {
BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tfacingwnormal = n;\n");
+ BLI_dynstr_append(ds, " facingwnormal = n;\n");
BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n");
BLI_dynstr_append(ds, "#endif\n");
}
else {
- BLI_dynstr_append(ds, "\tworld_normals_get(facingwnormal);\n");
+ BLI_dynstr_append(ds, " world_normals_get(facingwnormal);\n");
}
}
if (builtins & GPU_VIEW_POSITION) {
- BLI_dynstr_append(ds, "\t#define viewposition viewPosition\n");
+ BLI_dynstr_append(ds, " #define viewposition viewPosition\n");
}
codegen_declare_tmps(ds, graph);
@@ -610,21 +581,6 @@ static char *code_generate_fragment(GPUMaterial *material, GPUNodeGraph *graph)
BLI_dynstr_append(ds, "}\n");
- /* XXX This cannot go into gpu_shader_material.glsl because main()
- * would be parsed and generate error */
- /* Old glsl mode compat. */
- /* TODO(fclem) This is only used by world shader now. get rid of it? */
- BLI_dynstr_append(ds, "#ifndef NODETREE_EXEC\n");
- BLI_dynstr_append(ds, "out vec4 fragColor;\n");
- BLI_dynstr_append(ds, "void main()\n");
- BLI_dynstr_append(ds, "{\n");
- BLI_dynstr_append(ds, "\tClosure cl = nodetree_exec();\n");
- BLI_dynstr_append(ds,
- "\tfragColor = vec4(cl.radiance, "
- "saturate(1.0 - avg(cl.transmittance)));\n");
- BLI_dynstr_append(ds, "}\n");
- BLI_dynstr_append(ds, "#endif\n\n");
-
/* create shader */
code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -659,23 +615,48 @@ static const char *attr_prefix_get(CustomDataType type)
}
}
-static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bool use_geom)
+/* We talk about shader stage interface, not to be mistaken with GPUShaderInterface. */
+static char *code_generate_interface(GPUNodeGraph *graph, int builtins)
{
+ if (BLI_listbase_is_empty(&graph->attributes) &&
+ (builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0) {
+ return NULL;
+ }
+
DynStr *ds = BLI_dynstr_new();
- GPUNode *node;
- GPUInput *input;
- char *code;
- int builtins = 0;
- /* Hairs uv and col attributes are passed by bufferTextures. */
- BLI_dynstr_append(ds,
- "#ifdef HAIR_SHADER\n"
- "#define DEFINE_ATTR(type, attr) uniform samplerBuffer attr\n"
- "#else\n"
- "#define DEFINE_ATTR(type, attr) in type attr\n"
- "#endif\n");
+ BLI_dynstr_append(ds, "\n");
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
+ BLI_dynstr_appendf(ds, "%s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ }
+ if (builtins & GPU_BARYCENTRIC_TEXCO) {
+ BLI_dynstr_append(ds, "vec2 barycentricTexCo;\n");
+ }
+ if (builtins & GPU_BARYCENTRIC_DIST) {
+ BLI_dynstr_append(ds, "vec3 barycentricDist;\n");
+ }
+
+ char *code = BLI_dynstr_get_cstring(ds);
+
+ BLI_dynstr_free(ds);
+
+ return code;
+}
+
+static char *code_generate_vertex(GPUNodeGraph *graph,
+ const char *interface_str,
+ const char *vert_code,
+ int builtins)
+{
+ DynStr *ds = BLI_dynstr_new();
+
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
+
+ /* Inputs */
+ LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
+ const char *type_str = gpu_data_type_to_string(attr->gputype);
+ const char *prefix = attr_prefix_get(attr->type);
/* XXX FIXME : see notes in mesh_render_data_create() */
/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
if (attr->type == CD_ORCO) {
@@ -684,188 +665,58 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo
BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
}
else if (attr->name[0] == '\0') {
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s);\n",
- gpu_data_type_to_string(attr->gputype),
- attr_prefix_get(attr->type));
- BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, attr_prefix_get(attr->type));
+ BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s);\n", type_str, prefix);
+ BLI_dynstr_appendf(ds, "#define att%d %s\n", attr->id, prefix);
}
else {
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
GPU_vertformat_safe_attr_name(attr->name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
- BLI_dynstr_appendf(ds,
- "DEFINE_ATTR(%s, %s%s);\n",
- gpu_data_type_to_string(attr->gputype),
- attr_prefix_get(attr->type),
- attr_safe_name);
- BLI_dynstr_appendf(
- ds, "#define att%d %s%s\n", attr->id, attr_prefix_get(attr->type), attr_safe_name);
+ BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s%s);\n", type_str, prefix, attr_safe_name);
+ BLI_dynstr_appendf(ds, "#define att%d %s%s\n", attr->id, prefix, attr_safe_name);
}
- BLI_dynstr_appendf(ds,
- "out %s var%d%s;\n",
- gpu_data_type_to_string(attr->gputype),
- attr->id,
- use_geom ? "g" : "");
- }
-
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_BUILTIN) {
- builtins |= input->builtin;
- }
- }
- }
-
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_appendf(ds, "out vec2 barycentricTexCo%s;\n", use_geom ? "g" : "");
- BLI_dynstr_append(ds, "#endif\n");
}
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "out vec3 barycentricPosg;\n");
+ /* Outputs interface */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "out codegenInterface {%s};\n\n", interface_str);
}
- BLI_dynstr_append(ds, "\n#define USE_ATTR\n");
-
- /* Prototype, defined later (this is because of matrices definition). */
- BLI_dynstr_append(ds, "void pass_attr(in vec3 position);\n");
-
- BLI_dynstr_append(ds, "\n");
-
- if (use_geom) {
- /* XXX HACK: Eevee specific. */
- char *vert_new, *vert_new2;
- vert_new = BLI_str_replaceN(vert_code, "worldPosition", "worldPositiong");
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "viewPosition", "viewPositiong");
- MEM_freeN(vert_new2);
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "worldNormal", "worldNormalg");
- MEM_freeN(vert_new2);
- vert_new2 = vert_new;
- vert_new = BLI_str_replaceN(vert_new2, "viewNormal", "viewNormalg");
- MEM_freeN(vert_new2);
-
- BLI_dynstr_append(ds, vert_new);
-
- MEM_freeN(vert_new);
- }
- else {
- BLI_dynstr_append(ds, vert_code);
- }
+ /* Prototype. Needed for hair functions. */
+ BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv);\n");
+ BLI_dynstr_append(ds, "#define USE_ATTR\n\n");
+ BLI_dynstr_append(ds, vert_code);
BLI_dynstr_append(ds, "\n");
- BLI_dynstr_append(ds, use_geom ? "RESOURCE_ID_VARYING_GEOM\n" : "RESOURCE_ID_VARYING\n");
-
- /* Prototype because defined later. */
- BLI_dynstr_append(ds,
- "vec2 hair_get_customdata_vec2(const samplerBuffer);\n"
- "vec3 hair_get_customdata_vec3(const samplerBuffer);\n"
- "vec4 hair_get_customdata_vec4(const samplerBuffer);\n"
- "vec3 hair_get_strand_pos(void);\n"
- "int hair_get_base_id(void);\n"
- "\n");
-
- BLI_dynstr_append(ds, "void pass_attr(in vec3 position) {\n");
-
- BLI_dynstr_append(ds, use_geom ? "\tPASS_RESOURCE_ID_GEOM\n" : "\tPASS_RESOURCE_ID\n");
-
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
-
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- /* To match cycles without breaking into individual segment we encode if we need to invert
- * the first component into the second component. We invert if the barycentricTexCo.y
- * is NOT 0.0 or 1.0. */
- BLI_dynstr_append(ds, "\tint _base_id = hair_get_base_id();\n");
- BLI_dynstr_appendf(
- ds, "\tbarycentricTexCo%s.x = float((_base_id %% 2) == 1);\n", use_geom ? "g" : "");
- BLI_dynstr_appendf(
- ds, "\tbarycentricTexCo%s.y = float(((_base_id %% 4) %% 3) > 0);\n", use_geom ? "g" : "");
- }
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "\tbarycentricPosg = position;\n");
- }
-
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- if (attr->type == CD_TANGENT) {
- /* Not supported by hairs */
- BLI_dynstr_appendf(ds, "\tvar%d%s = vec4(0.0);\n", attr->id, use_geom ? "g" : "");
- }
- else if (attr->type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + (ModelMatrixInverse * "
- "vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1].xyz;\n",
- attr->id,
- use_geom ? "g" : "");
- /* TODO: fix ORCO with modifiers. */
- }
- else {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = hair_get_customdata_%s(att%d);\n",
- attr->id,
- use_geom ? "g" : "",
- gpu_data_type_to_string(attr->gputype),
- attr->id);
- }
- }
-
- BLI_dynstr_append(ds, "#else /* MESH_SHADER */\n");
+ BLI_dynstr_append(ds, "void pass_attr(vec3 position, mat3 normalmat, mat4 modelmatinv) {\n");
/* GPU_BARYCENTRIC_TEXCO cannot be computed based on gl_VertexID
* for MESH_SHADER because of indexed drawing. In this case a
* geometry shader is needed. */
-
+ if (builtins & GPU_BARYCENTRIC_TEXCO) {
+ BLI_dynstr_appendf(ds, " barycentricTexCo = barycentric_get();\n");
+ }
if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "\tbarycentricPosg = (ModelMatrix * vec4(position, 1.0)).xyz;\n");
+ BLI_dynstr_appendf(ds, " barycentricDist = vec3(0);\n");
}
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
if (attr->type == CD_TANGENT) { /* silly exception */
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz = transpose(mat3(ModelMatrixInverse)) * att%d.xyz;\n",
- attr->id,
- use_geom ? "g" : "",
- attr->id);
- BLI_dynstr_appendf(ds, "\tvar%d%s.w = att%d.w;\n", attr->id, use_geom ? "g" : "", attr->id);
- /* Normalize only if vector is not null. */
- BLI_dynstr_appendf(ds,
- "\tfloat lvar%d = dot(var%d%s.xyz, var%d%s.xyz);\n",
- attr->id,
- attr->id,
- use_geom ? "g" : "",
- attr->id,
- use_geom ? "g" : "");
- BLI_dynstr_appendf(ds,
- "\tvar%d%s.xyz *= (lvar%d > 0.0) ? inversesqrt(lvar%d) : 1.0;\n",
- attr->id,
- use_geom ? "g" : "",
- attr->id,
- attr->id);
+ BLI_dynstr_appendf(ds, " var%d = tangent_get(att%d, normalmat);\n", attr->id, attr->id);
}
else if (attr->type == CD_ORCO) {
- BLI_dynstr_appendf(ds,
- "\tvar%d%s = OrcoTexCoFactors[0].xyz + position *"
- " OrcoTexCoFactors[1].xyz;\n",
- attr->id,
- use_geom ? "g" : "");
- /* See mesh_create_loop_orco() for explanation. */
- BLI_dynstr_appendf(ds,
- "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
- attr->id,
- use_geom ? "g" : "");
+ BLI_dynstr_appendf(
+ ds, " var%d = orco_get(position, modelmatinv, OrcoTexCoFactors, orco);\n", attr->id);
}
else {
- BLI_dynstr_appendf(ds, "\tvar%d%s = att%d;\n", attr->id, use_geom ? "g" : "", attr->id);
+ const char *type_str = gpu_data_type_to_string(attr->gputype);
+ BLI_dynstr_appendf(ds, " var%d = GET_ATTR(%s, att%d);\n", attr->id, type_str, attr->id);
}
}
- BLI_dynstr_append(ds, "#endif /* HAIR_SHADER */\n");
BLI_dynstr_append(ds, "}\n");
- code = BLI_dynstr_get_cstring(ds);
+ char *code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -879,146 +730,46 @@ static char *code_generate_vertex(GPUNodeGraph *graph, const char *vert_code, bo
}
static char *code_generate_geometry(GPUNodeGraph *graph,
+ const char *interface_str,
const char *geom_code,
- const char *defines)
+ int builtins)
{
- DynStr *ds = BLI_dynstr_new();
- GPUNode *node;
- GPUInput *input;
- char *code;
- int builtins = 0;
-
- /* XXX we should not make specific eevee cases here. */
- bool is_hair_shader = (strstr(defines, "HAIR_SHADER") != NULL);
-
- /* Create prototype because attributes cannot be declared before layout. */
- BLI_dynstr_append(ds, "void pass_attr(in int vert);\n");
- BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2);\n");
- BLI_dynstr_append(ds, "#define USE_ATTR\n");
-
- /* Generate varying declarations. */
- for (node = graph->nodes.first; node; node = node->next) {
- for (input = node->inputs.first; input; input = input->next) {
- if (input->source == GPU_SOURCE_BUILTIN) {
- builtins |= input->builtin;
- }
- }
- }
-
- LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
- BLI_dynstr_appendf(ds, "in %s var%dg[];\n", gpu_data_type_to_string(attr->gputype), attr->id);
- BLI_dynstr_appendf(ds, "out %s var%d;\n", gpu_data_type_to_string(attr->gputype), attr->id);
+ if (!geom_code) {
+ return NULL;
}
- if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "in vec2 barycentricTexCog[];\n");
- BLI_dynstr_append(ds, "#endif\n");
-
- BLI_dynstr_append(ds, "out vec2 barycentricTexCo;\n");
- }
+ DynStr *ds = BLI_dynstr_new();
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "in vec3 barycentricPosg[];\n");
- BLI_dynstr_append(ds, "flat out vec3 barycentricDist;\n");
+ /* Attributes, Shader interface; */
+ if (interface_str) {
+ BLI_dynstr_appendf(ds, "in codegenInterface {%s} dataAttrIn[];\n\n", interface_str);
+ BLI_dynstr_appendf(ds, "out codegenInterface {%s} dataAttrOut;\n\n", interface_str);
}
- if (geom_code == NULL) {
- /* Force geometry usage if GPU_BARYCENTRIC_DIST or GPU_BARYCENTRIC_TEXCO are used.
- * Note: GPU_BARYCENTRIC_TEXCO only requires it if the shader is not drawing hairs. */
- if ((builtins & (GPU_BARYCENTRIC_DIST | GPU_BARYCENTRIC_TEXCO)) == 0 || is_hair_shader) {
- /* Early out */
- BLI_dynstr_free(ds);
- return NULL;
- }
- else {
- /* Force geom shader usage */
- /* TODO put in external file. */
- BLI_dynstr_append(ds, "layout(triangles) in;\n");
- BLI_dynstr_append(ds, "layout(triangle_strip, max_vertices=3) out;\n");
-
- BLI_dynstr_append(ds, "in vec3 worldPositiong[];\n");
- BLI_dynstr_append(ds, "in vec3 viewPositiong[];\n");
- BLI_dynstr_append(ds, "in vec3 worldNormalg[];\n");
- BLI_dynstr_append(ds, "in vec3 viewNormalg[];\n");
-
- BLI_dynstr_append(ds, "out vec3 worldPosition;\n");
- BLI_dynstr_append(ds, "out vec3 viewPosition;\n");
- BLI_dynstr_append(ds, "out vec3 worldNormal;\n");
- BLI_dynstr_append(ds, "out vec3 viewNormal;\n");
-
- BLI_dynstr_append(ds, datatoc_common_view_lib_glsl);
-
- BLI_dynstr_append(ds, "void main(){\n");
-
- if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds,
- "\tcalc_barycentric_distances(barycentricPosg[0], barycentricPosg[1], "
- "barycentricPosg[2]);\n");
- }
-
- for (int i = 0; i < 3; i++) {
- BLI_dynstr_appendf(ds, "\tgl_Position = gl_in[%d].gl_Position;\n", i);
- BLI_dynstr_appendf(ds, "\tgl_ClipDistance[0] = gl_in[%d].gl_ClipDistance[0];\n", i);
- BLI_dynstr_appendf(ds, "\tpass_attr(%d);\n", i);
- BLI_dynstr_append(ds, "\tEmitVertex();\n");
- }
- BLI_dynstr_append(ds, "}\n");
- }
- }
- else {
- BLI_dynstr_append(ds, geom_code);
- }
+ BLI_dynstr_append(ds, datatoc_gpu_shader_codegen_lib_glsl);
if (builtins & GPU_BARYCENTRIC_DIST) {
- BLI_dynstr_append(ds, "void calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2) {\n");
- BLI_dynstr_append(ds, "\tvec3 edge21 = pos2 - pos1;\n");
- BLI_dynstr_append(ds, "\tvec3 edge10 = pos1 - pos0;\n");
- BLI_dynstr_append(ds, "\tvec3 edge02 = pos0 - pos2;\n");
- BLI_dynstr_append(ds, "\tvec3 d21 = normalize(edge21);\n");
- BLI_dynstr_append(ds, "\tvec3 d10 = normalize(edge10);\n");
- BLI_dynstr_append(ds, "\tvec3 d02 = normalize(edge02);\n");
-
- BLI_dynstr_append(ds, "\tfloat d = dot(d21, edge02);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.x = sqrt(dot(edge02, edge02) - d * d);\n");
- BLI_dynstr_append(ds, "\td = dot(d02, edge10);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.y = sqrt(dot(edge10, edge10) - d * d);\n");
- BLI_dynstr_append(ds, "\td = dot(d10, edge21);\n");
- BLI_dynstr_append(ds, "\tbarycentricDist.z = sqrt(dot(edge21, edge21) - d * d);\n");
- BLI_dynstr_append(ds, "}\n");
+ /* geom_code should do something with this, but may not. */
+ BLI_dynstr_append(ds, "#define DO_BARYCENTRIC_DISTANCES\n");
}
- BLI_dynstr_append(ds, "RESOURCE_ID_VARYING\n");
-
/* Generate varying assignments. */
- BLI_dynstr_append(ds, "void pass_attr(in int vert) {\n");
-
- BLI_dynstr_append(ds, "\tPASS_RESOURCE_ID(vert)\n");
-
- /* XXX HACK: Eevee specific. */
- if (geom_code == NULL) {
- BLI_dynstr_append(ds, "\tworldPosition = worldPositiong[vert];\n");
- BLI_dynstr_append(ds, "\tviewPosition = viewPositiong[vert];\n");
- BLI_dynstr_append(ds, "\tworldNormal = worldNormalg[vert];\n");
- BLI_dynstr_append(ds, "\tviewNormal = viewNormalg[vert];\n");
- }
+ BLI_dynstr_append(ds, "#define USE_ATTR\n");
+ BLI_dynstr_append(ds, "void pass_attr(const int vert) {\n");
if (builtins & GPU_BARYCENTRIC_TEXCO) {
- BLI_dynstr_append(ds, "#ifdef HAIR_SHADER\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo = barycentricTexCog[vert];\n");
- BLI_dynstr_append(ds, "#else\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo.x = float((vert % 3) == 0);\n");
- BLI_dynstr_append(ds, "\tbarycentricTexCo.y = float((vert % 3) == 1);\n");
- BLI_dynstr_append(ds, "#endif\n");
+ BLI_dynstr_append(ds, " dataAttrOut.barycentricTexCo = calc_barycentric_co(vert);\n");
}
LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) {
/* TODO let shader choose what to do depending on what the attribute is. */
- BLI_dynstr_appendf(ds, "\tvar%d = var%dg[vert];\n", attr->id, attr->id);
+ BLI_dynstr_appendf(ds, " dataAttrOut.var%d = dataAttrIn[vert].var%d;\n", attr->id, attr->id);
}
- BLI_dynstr_append(ds, "}\n");
+ BLI_dynstr_append(ds, "}\n\n");
- code = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_append(ds, geom_code);
+
+ char *code = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
return code;
@@ -1048,8 +799,17 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
* generated VBOs are ready to accept the future shader. */
gpu_node_graph_prune_unused(graph);
+ int builtins = 0;
+ LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) {
+ LISTBASE_FOREACH (GPUInput *, input, &node->inputs) {
+ if (input->source == GPU_SOURCE_BUILTIN) {
+ builtins |= input->builtin;
+ }
+ }
+ }
/* generate code */
- char *fragmentgen = code_generate_fragment(material, graph);
+ char *interface_str = code_generate_interface(graph, builtins);
+ char *fragmentgen = code_generate_fragment(material, graph, interface_str);
/* Cache lookup: Reuse shaders already compiled */
uint32_t hash = gpu_pass_hash(fragmentgen, defines, &graph->attributes);
@@ -1057,6 +817,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
if (pass_hash && (pass_hash->next == NULL || pass_hash->next->hash != hash)) {
/* No collision, just return the pass. */
+ MEM_SAFE_FREE(interface_str);
MEM_freeN(fragmentgen);
if (!gpu_pass_is_valid(pass_hash)) {
/* Shader has already been created but failed to compile. */
@@ -1071,10 +832,11 @@ GPUPass *GPU_generate_pass(GPUMaterial *material,
GSet *used_libraries = gpu_material_used_libraries(material);
char *tmp = gpu_material_library_generate_code(used_libraries, frag_lib);
- char *geometrycode = code_generate_geometry(graph, geom_code, defines);
- char *vertexcode = code_generate_vertex(graph, vert_code, (geometrycode != NULL));
+ char *geometrycode = code_generate_geometry(graph, interface_str, geom_code, builtins);
+ char *vertexcode = code_generate_vertex(graph, interface_str, vert_code, builtins);
char *fragmentcode = BLI_strdupcat(tmp, fragmentgen);
+ MEM_SAFE_FREE(interface_str);
MEM_freeN(fragmentgen);
MEM_freeN(tmp);
diff --git a/source/blender/gpu/intern/gpu_codegen.h b/source/blender/gpu/intern/gpu_codegen.h
index 1454edeb1e0..5d130d75d2c 100644
--- a/source/blender/gpu/intern/gpu_codegen.h
+++ b/source/blender/gpu/intern/gpu_codegen.h
@@ -25,6 +25,10 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct GPUMaterial;
struct GPUNodeGraph;
struct GPUOutput;
@@ -61,3 +65,7 @@ void GPU_pass_release(GPUPass *pass);
void gpu_codegen_init(void);
void gpu_codegen_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_context.cpp b/source/blender/gpu/intern/gpu_context.cc
index e6356580ea3..e6356580ea3 100644
--- a/source/blender/gpu/intern/gpu_context.cpp
+++ b/source/blender/gpu/intern/gpu_context.cc
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.cc
index f7d6236071d..f7d6236071d 100644
--- a/source/blender/gpu/intern/gpu_debug.c
+++ b/source/blender/gpu/intern/gpu_debug.cc
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
deleted file mode 100644
index e5f49555265..00000000000
--- a/source/blender/gpu/intern/gpu_draw.c
+++ /dev/null
@@ -1,1469 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2005 Blender Foundation.
- * All rights reserved.
- */
-
-/** \file
- * \ingroup gpu
- *
- * Utility functions for dealing with OpenGL texture & material context,
- * mipmap generation and light objects.
- *
- * These are some obscure rendering functions shared between the game engine (not anymore)
- * and the blender, in this module to avoid duplication
- * and abstract them away from the rest a bit.
- */
-
-#include <string.h>
-
-#include "BLI_blenlib.h"
-#include "BLI_boxpack_2d.h"
-#include "BLI_linklist.h"
-#include "BLI_math.h"
-#include "BLI_threads.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_image_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_userdef_types.h"
-
-#include "MEM_guardedalloc.h"
-
-#include "IMB_colormanagement.h"
-#include "IMB_imbuf.h"
-#include "IMB_imbuf_types.h"
-
-#include "BKE_global.h"
-#include "BKE_image.h"
-#include "BKE_main.h"
-#include "BKE_movieclip.h"
-
-#include "GPU_draw.h"
-#include "GPU_extensions.h"
-#include "GPU_glew.h"
-#include "GPU_matrix.h"
-#include "GPU_platform.h"
-#include "GPU_texture.h"
-
-#include "PIL_time.h"
-
-static void gpu_free_image(Image *ima, const bool immediate);
-static void gpu_free_unused_buffers(void);
-
-//* Checking powers of two for images since OpenGL ES requires it */
-#ifdef WITH_DDS
-static bool is_power_of_2_resolution(int w, int h)
-{
- return is_power_of_2_i(w) && is_power_of_2_i(h);
-}
-#endif
-
-static bool is_over_resolution_limit(GLenum textarget, int w, int h)
-{
- int size = (textarget == GL_TEXTURE_CUBE_MAP) ? GPU_max_cube_map_size() : GPU_max_texture_size();
- int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size;
-
- return (w > reslimit || h > reslimit);
-}
-
-static int smaller_power_of_2_limit(int num)
-{
- int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, GPU_max_texture_size()) :
- GPU_max_texture_size();
- /* take texture clamping into account */
- if (num > reslimit) {
- return reslimit;
- }
-
- return power_of_2_min_i(num);
-}
-
-/* Current OpenGL state caching for GPU_set_tpage */
-
-static struct GPUTextureState {
- /* also controls min/mag filtering */
- bool domipmap;
- /* only use when 'domipmap' is set */
- bool linearmipmap;
- /* store this so that new images created while texture painting won't be set to mipmapped */
- bool texpaint;
-
- float anisotropic;
-} GTS = {1, 0, 0, 1.0f};
-
-/* Mipmap settings */
-
-void GPU_set_mipmap(Main *bmain, bool mipmap)
-{
- if (GTS.domipmap != mipmap) {
- GPU_free_images(bmain);
- GTS.domipmap = mipmap;
- }
-}
-
-void GPU_set_linear_mipmap(bool linear)
-{
- if (GTS.linearmipmap != linear) {
- GTS.linearmipmap = linear;
- }
-}
-
-bool GPU_get_mipmap(void)
-{
- return GTS.domipmap && !GTS.texpaint;
-}
-
-bool GPU_get_linear_mipmap(void)
-{
- return GTS.linearmipmap;
-}
-
-static GLenum gpu_get_mipmap_filter(bool mag)
-{
- /* linearmipmap is off by default *when mipmapping is off,
- * use unfiltered display */
- if (mag) {
- if (GTS.domipmap) {
- return GL_LINEAR;
- }
- else {
- return GL_NEAREST;
- }
- }
- else {
- if (GTS.domipmap) {
- if (GTS.linearmipmap) {
- return GL_LINEAR_MIPMAP_LINEAR;
- }
- else {
- return GL_LINEAR_MIPMAP_NEAREST;
- }
- }
- else {
- return GL_NEAREST;
- }
- }
-}
-
-/* Anisotropic filtering settings */
-void GPU_set_anisotropic(float value)
-{
- if (GTS.anisotropic != value) {
- GPU_samplers_free();
-
- /* Clamp value to the maximum value the graphics card supports */
- const float max = GPU_max_texture_anisotropy();
- if (value > max) {
- value = max;
- }
-
- GTS.anisotropic = value;
-
- GPU_samplers_init();
- }
-}
-
-float GPU_get_anisotropic(void)
-{
- return GTS.anisotropic;
-}
-
-/* Set OpenGL state for an MTFace */
-
-static GPUTexture **gpu_get_image_gputexture(Image *ima, GLenum textarget, const int multiview_eye)
-{
- if (textarget == GL_TEXTURE_2D) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_2D][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_CUBE_MAP][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_2D_ARRAY) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye]);
- }
- else if (textarget == GL_TEXTURE_1D_ARRAY) {
- return &(ima->gputexture[TEXTARGET_TEXTURE_TILE_MAPPING][multiview_eye]);
- }
-
- return NULL;
-}
-
-static uint gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
-{
- GPUTexture *tilearray = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][multiview_eye];
-
- if (tilearray == NULL) {
- return 0;
- }
-
- float array_w = GPU_texture_width(tilearray);
- float array_h = GPU_texture_height(tilearray);
-
- ImageTile *last_tile = ima->tiles.last;
- /* Tiles are sorted by number. */
- int max_tile = last_tile->tile_number - 1001;
-
- /* create image */
- int bindcode;
- glGenTextures(1, (GLuint *)&bindcode);
- glBindTexture(GL_TEXTURE_1D_ARRAY, bindcode);
-
- int width = max_tile + 1;
- float *data = MEM_callocN(width * 8 * sizeof(float), __func__);
- for (int i = 0; i < width; i++) {
- data[4 * i] = -1.0f;
- }
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- int i = tile->tile_number - 1001;
- data[4 * i] = tile->runtime.tilearray_layer;
-
- float *tile_info = &data[4 * width + 4 * i];
- tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
- tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
- tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
- tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
- }
-
- glTexImage2D(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA32F, width, 2, 0, GL_RGBA, GL_FLOAT, data);
- MEM_freeN(data);
-
- glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-
- glBindTexture(GL_TEXTURE_1D_ARRAY, 0);
-
- return bindcode;
-}
-
-typedef struct PackTile {
- FixedSizeBoxPack boxpack;
- ImageTile *tile;
- float pack_score;
-} PackTile;
-
-static int compare_packtile(const void *a, const void *b)
-{
- const PackTile *tile_a = a;
- const PackTile *tile_b = b;
-
- return tile_a->pack_score < tile_b->pack_score;
-}
-
-static uint gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
-{
- int arraywidth = 0, arrayheight = 0;
-
- ListBase boxes = {NULL};
-
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
- iuser.tile = tile->tile_number;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
-
- if (ibuf) {
- PackTile *packtile = MEM_callocN(sizeof(PackTile), __func__);
- packtile->tile = tile;
- packtile->boxpack.w = ibuf->x;
- packtile->boxpack.h = ibuf->y;
-
- if (is_over_resolution_limit(
- GL_TEXTURE_2D_ARRAY, packtile->boxpack.w, packtile->boxpack.h)) {
- packtile->boxpack.w = smaller_power_of_2_limit(packtile->boxpack.w);
- packtile->boxpack.h = smaller_power_of_2_limit(packtile->boxpack.h);
- }
- arraywidth = max_ii(arraywidth, packtile->boxpack.w);
- arrayheight = max_ii(arrayheight, packtile->boxpack.h);
-
- /* We sort the tiles by decreasing size, with an additional penalty term
- * for high aspect ratios. This improves packing efficiency. */
- float w = packtile->boxpack.w, h = packtile->boxpack.h;
- packtile->pack_score = max_ff(w, h) / min_ff(w, h) * w * h;
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- BLI_addtail(&boxes, packtile);
- }
- }
-
- BLI_assert(arraywidth > 0 && arrayheight > 0);
-
- BLI_listbase_sort(&boxes, compare_packtile);
- int arraylayers = 0;
- /* Keep adding layers until all tiles are packed. */
- while (boxes.first != NULL) {
- ListBase packed = {NULL};
- BLI_box_pack_2d_fixedarea(&boxes, arraywidth, arrayheight, &packed);
- BLI_assert(packed.first != NULL);
-
- LISTBASE_FOREACH (PackTile *, packtile, &packed) {
- ImageTile *tile = packtile->tile;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
-
- tileoffset[0] = packtile->boxpack.x;
- tileoffset[1] = packtile->boxpack.y;
- tilesize[0] = packtile->boxpack.w;
- tilesize[1] = packtile->boxpack.h;
- tile->runtime.tilearray_layer = arraylayers;
- }
-
- BLI_freelistN(&packed);
- arraylayers++;
- }
-
- /* create image */
- int bindcode;
- glGenTextures(1, (GLuint *)&bindcode);
- glBindTexture(GL_TEXTURE_2D_ARRAY, bindcode);
-
- GLenum data_type, internal_format;
- if (main_ibuf->rect_float) {
- data_type = GL_FLOAT;
- internal_format = (!(main_ibuf->flags & IB_halffloat) && (ima->flag & IMA_HIGH_BITDEPTH)) ?
- GL_RGBA32F :
- GL_RGBA16F;
- }
- else {
- data_type = GL_UNSIGNED_BYTE;
- internal_format = GL_RGBA8;
- if (!IMB_colormanagement_space_is_data(main_ibuf->rect_colorspace) &&
- !IMB_colormanagement_space_is_scene_linear(main_ibuf->rect_colorspace)) {
- internal_format = GL_SRGB8_ALPHA8;
- }
- }
-
- glTexImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- internal_format,
- arraywidth,
- arrayheight,
- arraylayers,
- 0,
- GL_RGBA,
- data_type,
- NULL);
-
- LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- int tilelayer = tile->runtime.tilearray_layer;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
-
- if (tilesize[0] == 0 || tilesize[1] == 0) {
- continue;
- }
-
- ImageUser iuser;
- BKE_imageuser_default(&iuser);
- iuser.tile = tile->tile_number;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
-
- if (ibuf) {
- bool needs_scale = (ibuf->x != tilesize[0] || ibuf->y != tilesize[1]);
-
- ImBuf *scale_ibuf = NULL;
- if (ibuf->rect_float) {
- float *rect_float = ibuf->rect_float;
-
- const bool store_premultiplied = ima->alpha_mode != IMA_ALPHA_STRAIGHT;
- if (ibuf->channels != 4 || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
- }
-
- float *pixeldata = rect_float;
- if (needs_scale) {
- scale_ibuf = IMB_allocFromBuffer(NULL, rect_float, ibuf->x, ibuf->y, 4);
- IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]);
- pixeldata = scale_ibuf->rect_float;
- }
-
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- tileoffset[0],
- tileoffset[1],
- tilelayer,
- tilesize[0],
- tilesize[1],
- 1,
- GL_RGBA,
- GL_FLOAT,
- pixeldata);
-
- if (rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
- }
- else {
- unsigned int *rect = ibuf->rect;
-
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
- IMB_colormanagement_imbuf_to_byte_texture((uchar *)rect,
- 0,
- 0,
- ibuf->x,
- ibuf->y,
- ibuf,
- internal_format == GL_SRGB8_ALPHA8,
- ima->alpha_mode == IMA_ALPHA_PREMUL);
- }
-
- unsigned int *pixeldata = rect;
- if (needs_scale) {
- scale_ibuf = IMB_allocFromBuffer(rect, NULL, ibuf->x, ibuf->y, 4);
- IMB_scaleImBuf(scale_ibuf, tilesize[0], tilesize[1]);
- pixeldata = scale_ibuf->rect;
- }
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- tileoffset[0],
- tileoffset[1],
- tilelayer,
- tilesize[0],
- tilesize[1],
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- pixeldata);
-
- if (rect != ibuf->rect) {
- MEM_freeN(rect);
- }
- }
- if (scale_ibuf != NULL) {
- IMB_freeImBuf(scale_ibuf);
- }
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
-
- glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
-
- return bindcode;
-}
-
-static uint gpu_texture_create_from_ibuf(Image *ima, ImBuf *ibuf, int textarget)
-{
- uint bindcode = 0;
- const bool mipmap = GPU_get_mipmap();
- const bool half_float = (ibuf->flags & IB_halffloat) != 0;
-
-#ifdef WITH_DDS
- if (ibuf->ftype == IMB_FTYPE_DDS) {
- /* DDS is loaded directly in compressed form. */
- GPU_create_gl_tex_compressed(&bindcode, textarget, ima, ibuf);
- return bindcode;
- }
-#endif
-
- /* Regular uncompressed texture. */
- float *rect_float = ibuf->rect_float;
- uchar *rect = (uchar *)ibuf->rect;
- bool compress_as_srgb = false;
-
- if (rect_float == NULL) {
- /* Byte image is in original colorspace from the file. If the file is sRGB
- * scene linear, or non-color data no conversion is needed. Otherwise we
- * compress as scene linear + sRGB transfer function to avoid precision loss
- * in common cases.
- *
- * We must also convert to premultiplied for correct texture interpolation
- * and consistency with float images. */
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace);
-
- rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
- if (rect == NULL) {
- return bindcode;
- }
-
- /* Texture storage of images is defined by the alpha mode of the image. The
- * downside of this is that there can be artifacts near alpha edges. However,
- * this allows us to use sRGB texture formats and preserves color values in
- * zero alpha areas, and appears generally closer to what game engines that we
- * want to be compatible with do. */
- const bool store_premultiplied = ima ? (ima->alpha_mode == IMA_ALPHA_PREMUL) : true;
- IMB_colormanagement_imbuf_to_byte_texture(
- rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied);
- }
- }
- else {
- /* Float image is already in scene linear colorspace or non-color data by
- * convention, no colorspace conversion needed. But we do require 4 channels
- * currently. */
- const bool store_premultiplied = ima ? (ima->alpha_mode != IMA_ALPHA_STRAIGHT) : false;
-
- if (ibuf->channels != 4 || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
- if (rect_float == NULL) {
- return bindcode;
- }
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
- }
- }
-
- /* Create OpenGL texture. */
- GPU_create_gl_tex(&bindcode,
- (uint *)rect,
- rect_float,
- ibuf->x,
- ibuf->y,
- textarget,
- mipmap,
- half_float,
- compress_as_srgb,
- ima);
-
- /* Free buffers if needed. */
- if (rect && rect != (uchar *)ibuf->rect) {
- MEM_freeN(rect);
- }
- if (rect_float && rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
-
- return bindcode;
-}
-
-static GPUTexture **gpu_get_movieclip_gputexture(MovieClip *clip,
- MovieClipUser *cuser,
- GLenum textarget)
-{
- MovieClip_RuntimeGPUTexture *tex;
- for (tex = clip->runtime.gputextures.first; tex; tex = tex->next) {
- if (memcmp(&tex->user, cuser, sizeof(MovieClipUser)) == 0) {
- break;
- }
- }
-
- if (tex == NULL) {
- tex = MEM_mallocN(sizeof(MovieClip_RuntimeGPUTexture), __func__);
-
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- tex->gputexture[i] = NULL;
- }
-
- memcpy(&tex->user, cuser, sizeof(MovieClipUser));
- BLI_addtail(&clip->runtime.gputextures, tex);
- }
-
- if (textarget == GL_TEXTURE_2D) {
- return &tex->gputexture[TEXTARGET_TEXTURE_2D];
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- return &tex->gputexture[TEXTARGET_TEXTURE_CUBE_MAP];
- }
-
- return NULL;
-}
-
-static ImBuf *update_do_scale(uchar *rect,
- float *rect_float,
- int *x,
- int *y,
- int *w,
- int *h,
- int limit_w,
- int limit_h,
- int full_w,
- int full_h)
-{
- /* Partial update with scaling. */
- float xratio = limit_w / (float)full_w;
- float yratio = limit_h / (float)full_h;
-
- int part_w = *w, part_h = *h;
-
- /* Find sub coordinates in scaled image. Take ceiling because we will be
- * losing 1 pixel due to rounding errors in x,y. */
- *x *= xratio;
- *y *= yratio;
- *w = (int)ceil(xratio * (*w));
- *h = (int)ceil(yratio * (*h));
-
- /* ...but take back if we are over the limit! */
- if (*x + *w > limit_w) {
- (*w)--;
- }
- if (*y + *h > limit_h) {
- (*h)--;
- }
-
- /* Scale pixels. */
- ImBuf *ibuf = IMB_allocFromBuffer((uint *)rect, rect_float, part_w, part_h, 4);
- IMB_scaleImBuf(ibuf, *w, *h);
-
- return ibuf;
-}
-
-static void gpu_texture_update_scaled_array(uchar *rect,
- float *rect_float,
- int full_w,
- int full_h,
- int x,
- int y,
- int layer,
- const int *tile_offset,
- const int *tile_size,
- int w,
- int h)
-{
- ImBuf *ibuf = update_do_scale(
- rect, rect_float, &x, &y, &w, &h, tile_size[0], tile_size[1], full_w, full_h);
-
- /* Shift to account for tile packing. */
- x += tile_offset[0];
- y += tile_offset[1];
-
- if (ibuf->rect_float) {
- glTexSubImage3D(
- GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_FLOAT, ibuf->rect_float);
- }
- else {
- glTexSubImage3D(
- GL_TEXTURE_2D_ARRAY, 0, x, y, layer, w, h, 1, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- }
-
- IMB_freeImBuf(ibuf);
-}
-
-static void gpu_texture_update_scaled(
- uchar *rect, float *rect_float, int full_w, int full_h, int x, int y, int w, int h)
-{
- /* Partial update with scaling. */
- int limit_w = smaller_power_of_2_limit(full_w);
- int limit_h = smaller_power_of_2_limit(full_h);
-
- ImBuf *ibuf = update_do_scale(
- rect, rect_float, &x, &y, &w, &h, limit_w, limit_h, full_w, full_h);
-
- if (ibuf->rect_float) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, ibuf->rect_float);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- }
-
- IMB_freeImBuf(ibuf);
-}
-
-static void gpu_texture_update_unscaled(uchar *rect,
- float *rect_float,
- int x,
- int y,
- int layer,
- int w,
- int h,
- GLint tex_stride,
- GLint tex_offset)
-{
- /* Partial update without scaling. Stride and offset are used to copy only a
- * subset of a possible larger buffer than what we are updating. */
- GPU_unpack_row_length_set(tex_stride);
-
- if (layer >= 0) {
- if (rect_float == NULL) {
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- x,
- y,
- layer,
- w,
- h,
- 1,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- rect + tex_offset);
- }
- else {
- glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
- 0,
- x,
- y,
- layer,
- w,
- h,
- 1,
- GL_RGBA,
- GL_FLOAT,
- rect_float + tex_offset);
- }
- }
- else {
- if (rect_float == NULL) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect + tex_offset);
- }
- else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_FLOAT, rect_float + tex_offset);
- }
- }
-
- /* Restore default. */
- GPU_unpack_row_length_set(0);
-}
-
-static void gpu_texture_update_from_ibuf(
- GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
-{
- /* Partial update of texture for texture painting. This is often much
- * quicker than fully updating the texture for high resolution images. */
- GPU_texture_bind(tex, 0);
-
- bool scaled;
- if (tile != NULL) {
- int *tilesize = tile->runtime.tilearray_size;
- scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
- }
- else {
- scaled = is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y);
- }
-
- if (scaled) {
- /* Extra padding to account for bleed from neighboring pixels. */
- const int padding = 4;
- const int xmax = min_ii(x + w + padding, ibuf->x);
- const int ymax = min_ii(y + h + padding, ibuf->y);
- x = max_ii(x - padding, 0);
- y = max_ii(y - padding, 0);
- w = xmax - x;
- h = ymax - y;
- }
-
- /* Get texture data pointers. */
- float *rect_float = ibuf->rect_float;
- uchar *rect = (uchar *)ibuf->rect;
- GLint tex_stride = ibuf->x;
- GLint tex_offset = ibuf->channels * (y * ibuf->x + x);
-
- if (rect_float == NULL) {
- /* Byte pixels. */
- if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
- const bool compress_as_srgb = !IMB_colormanagement_space_is_scene_linear(
- ibuf->rect_colorspace);
-
- rect = MEM_mallocN(sizeof(uchar) * 4 * w * h, __func__);
- if (rect == NULL) {
- return;
- }
-
- tex_stride = w;
- tex_offset = 0;
-
- /* Convert to scene linear with sRGB compression, and premultiplied for
- * correct texture interpolation. */
- const bool store_premultiplied = (ima->alpha_mode == IMA_ALPHA_PREMUL);
- IMB_colormanagement_imbuf_to_byte_texture(
- rect, x, y, w, h, ibuf, compress_as_srgb, store_premultiplied);
- }
- }
- else {
- /* Float pixels. */
- const bool store_premultiplied = (ima->alpha_mode != IMA_ALPHA_STRAIGHT);
-
- if (ibuf->channels != 4 || scaled || !store_premultiplied) {
- rect_float = MEM_mallocN(sizeof(float) * 4 * w * h, __func__);
- if (rect_float == NULL) {
- return;
- }
-
- tex_stride = w;
- tex_offset = 0;
-
- IMB_colormanagement_imbuf_to_float_texture(
- rect_float, x, y, w, h, ibuf, store_premultiplied);
- }
- }
-
- if (scaled) {
- /* Slower update where we first have to scale the input pixels. */
- if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
- int tilelayer = tile->runtime.tilearray_layer;
- gpu_texture_update_scaled_array(
- rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
- }
- else {
- gpu_texture_update_scaled(rect, rect_float, ibuf->x, ibuf->y, x, y, w, h);
- }
- }
- else {
- /* Fast update at same resolution. */
- if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int tilelayer = tile->runtime.tilearray_layer;
- gpu_texture_update_unscaled(rect,
- rect_float,
- x + tileoffset[0],
- y + tileoffset[1],
- tilelayer,
- w,
- h,
- tex_stride,
- tex_offset);
- }
- else {
- gpu_texture_update_unscaled(rect, rect_float, x, y, -1, w, h, tex_stride, tex_offset);
- }
- }
-
- /* Free buffers if needed. */
- if (rect && rect != (uchar *)ibuf->rect) {
- MEM_freeN(rect);
- }
- if (rect_float && rect_float != ibuf->rect_float) {
- MEM_freeN(rect_float);
- }
-
- if (GPU_get_mipmap()) {
- glGenerateMipmap((tile != NULL) ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D);
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
-
- GPU_texture_unbind(tex);
-}
-
-/* Get the GPUTexture for a given `Image`.
- *
- * `iuser` and `ibuf` are mutual exclusive parameters. The caller can pass the `ibuf` when already
- * available. It is also required when requesting the GPUTexture for a render result. */
-GPUTexture *GPU_texture_from_blender(Image *ima, ImageUser *iuser, ImBuf *ibuf, int textarget)
-{
-#ifndef GPU_STANDALONE
- if (ima == NULL) {
- return NULL;
- }
-
- /* Free any unused GPU textures, since we know we are in a thread with OpenGL
- * context and might as well ensure we have as much space free as possible. */
- gpu_free_unused_buffers();
-
- /* currently, gpu refresh tagging is used by ima sequences */
- if (ima->gpuflag & IMA_GPU_REFRESH) {
- gpu_free_image(ima, true);
- ima->gpuflag &= ~IMA_GPU_REFRESH;
- }
-
- /* Tag as in active use for garbage collector. */
- BKE_image_tag_time(ima);
-
- /* Test if we already have a texture. */
- GPUTexture **tex = gpu_get_image_gputexture(ima, textarget, iuser ? iuser->multiview_eye : 0);
- if (*tex) {
- return *tex;
- }
-
- /* Check if we have a valid image. If not, we return a dummy
- * texture with zero bindcode so we don't keep trying. */
- uint bindcode = 0;
- ImageTile *tile = BKE_image_get_tile(ima, 0);
- if (tile == NULL || tile->ok == 0) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
-
- /* check if we have a valid image buffer */
- ImBuf *ibuf_intern = ibuf;
- if (ibuf_intern == NULL) {
- ibuf_intern = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if (ibuf_intern == NULL) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
- }
-
- if (textarget == GL_TEXTURE_2D_ARRAY) {
- bindcode = gpu_texture_create_tile_array(ima, ibuf_intern);
- }
- else if (textarget == GL_TEXTURE_1D_ARRAY) {
- bindcode = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
- }
- else {
- bindcode = gpu_texture_create_from_ibuf(ima, ibuf_intern, textarget);
- }
-
- /* if `ibuf` was given, we don't own the `ibuf_intern` */
- if (ibuf == NULL) {
- BKE_image_release_ibuf(ima, ibuf_intern, NULL);
- }
-
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
-
- GPU_texture_orig_size_set(*tex, ibuf_intern->x, ibuf_intern->y);
-
- if (textarget == GL_TEXTURE_1D_ARRAY) {
- /* Special for tile mapping. */
- GPU_texture_mipmap_mode(*tex, false, false);
- }
-
- return *tex;
-#endif
- return NULL;
-}
-
-GPUTexture *GPU_texture_from_movieclip(MovieClip *clip, MovieClipUser *cuser, int textarget)
-{
-#ifndef GPU_STANDALONE
- if (clip == NULL) {
- return NULL;
- }
-
- GPUTexture **tex = gpu_get_movieclip_gputexture(clip, cuser, textarget);
- if (*tex) {
- return *tex;
- }
-
- /* check if we have a valid image buffer */
- uint bindcode = 0;
- ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, cuser);
- if (ibuf == NULL) {
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
- }
-
- bindcode = gpu_texture_create_from_ibuf(NULL, ibuf, textarget);
- IMB_freeImBuf(ibuf);
-
- *tex = GPU_texture_from_bindcode(textarget, bindcode);
- return *tex;
-#else
- return NULL;
-#endif
-}
-
-void GPU_free_texture_movieclip(struct MovieClip *clip)
-{
- /* number of gpu textures to keep around as cache
- * We don't want to keep too many GPU textures for
- * movie clips around, as they can be large.*/
- const int MOVIECLIP_NUM_GPUTEXTURES = 1;
-
- while (BLI_listbase_count(&clip->runtime.gputextures) > MOVIECLIP_NUM_GPUTEXTURES) {
- MovieClip_RuntimeGPUTexture *tex = BLI_pophead(&clip->runtime.gputextures);
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- /* free glsl image binding */
- if (tex->gputexture[i]) {
- GPU_texture_free(tex->gputexture[i]);
- tex->gputexture[i] = NULL;
- }
- }
- MEM_freeN(tex);
- }
-}
-
-static void **gpu_gen_cube_map(uint *rect, float *frect, int rectw, int recth)
-{
- size_t block_size = frect ? sizeof(float[4]) : sizeof(uchar[4]);
- void **sides = NULL;
- int h = recth / 2;
- int w = rectw / 3;
-
- if (w != h) {
- return sides;
- }
-
- /* PosX, NegX, PosY, NegY, PosZ, NegZ */
- sides = MEM_mallocN(sizeof(void *) * 6, "");
- for (int i = 0; i < 6; i++) {
- sides[i] = MEM_mallocN(block_size * w * h, "");
- }
-
- /* divide image into six parts */
- /* ______________________
- * | | | |
- * | NegX | NegY | PosX |
- * |______|______|______|
- * | | | |
- * | NegZ | PosZ | PosY |
- * |______|______|______|
- */
- if (frect) {
- float(*frectb)[4] = (float(*)[4])frect;
- float(**fsides)[4] = (float(**)[4])sides;
-
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- memcpy(&fsides[0][x * h + y], &frectb[(recth - y - 1) * rectw + 2 * w + x], block_size);
- memcpy(&fsides[1][x * h + y], &frectb[(y + h) * rectw + w - 1 - x], block_size);
- memcpy(
- &fsides[3][y * w + x], &frectb[(recth - y - 1) * rectw + 2 * w - 1 - x], block_size);
- memcpy(&fsides[5][y * w + x], &frectb[(h - y - 1) * rectw + w - 1 - x], block_size);
- }
- memcpy(&fsides[2][y * w], frectb[y * rectw + 2 * w], block_size * w);
- memcpy(&fsides[4][y * w], frectb[y * rectw + w], block_size * w);
- }
- }
- else {
- uint **isides = (uint **)sides;
-
- for (int y = 0; y < h; y++) {
- for (int x = 0; x < w; x++) {
- isides[0][x * h + y] = rect[(recth - y - 1) * rectw + 2 * w + x];
- isides[1][x * h + y] = rect[(y + h) * rectw + w - 1 - x];
- isides[3][y * w + x] = rect[(recth - y - 1) * rectw + 2 * w - 1 - x];
- isides[5][y * w + x] = rect[(h - y - 1) * rectw + w - 1 - x];
- }
- memcpy(&isides[2][y * w], &rect[y * rectw + 2 * w], block_size * w);
- memcpy(&isides[4][y * w], &rect[y * rectw + w], block_size * w);
- }
- }
-
- return sides;
-}
-
-static void gpu_del_cube_map(void **cube_map)
-{
- int i;
- if (cube_map == NULL) {
- return;
- }
- for (i = 0; i < 6; i++) {
- MEM_freeN(cube_map[i]);
- }
- MEM_freeN(cube_map);
-}
-
-/* Image *ima can be NULL */
-void GPU_create_gl_tex(uint *bind,
- uint *rect,
- float *frect,
- int rectw,
- int recth,
- int textarget,
- bool mipmap,
- bool half_float,
- bool use_srgb,
- Image *ima)
-{
- ImBuf *ibuf = NULL;
-
- if (textarget == GL_TEXTURE_2D && is_over_resolution_limit(textarget, rectw, recth)) {
- int tpx = rectw;
- int tpy = recth;
- rectw = smaller_power_of_2_limit(rectw);
- recth = smaller_power_of_2_limit(recth);
-
- if (frect) {
- ibuf = IMB_allocFromBuffer(NULL, frect, tpx, tpy, 4);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- frect = ibuf->rect_float;
- }
- else {
- ibuf = IMB_allocFromBuffer(rect, NULL, tpx, tpy, 4);
- IMB_scaleImBuf(ibuf, rectw, recth);
-
- rect = ibuf->rect;
- }
- }
-
- /* create image */
- glGenTextures(1, (GLuint *)bind);
- glBindTexture(textarget, *bind);
-
- GLenum float_format = (!half_float && (ima && (ima->flag & IMA_HIGH_BITDEPTH))) ? GL_RGBA32F :
- GL_RGBA16F;
- GLenum internal_format = (frect) ? float_format : (use_srgb) ? GL_SRGB8_ALPHA8 : GL_RGBA8;
-
- if (textarget == GL_TEXTURE_2D) {
- if (frect) {
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_FLOAT, frect);
- }
- else {
- glTexImage2D(
- GL_TEXTURE_2D, 0, internal_format, rectw, recth, 0, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- }
-
- if (GPU_get_mipmap() && mipmap) {
- glGenerateMipmap(GL_TEXTURE_2D);
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
- else if (textarget == GL_TEXTURE_CUBE_MAP) {
- int w = rectw / 3, h = recth / 2;
-
- if (h == w && is_power_of_2_i(h) && !is_over_resolution_limit(textarget, h, w)) {
- void **cube_map = gpu_gen_cube_map(rect, frect, rectw, recth);
- GLenum type = frect ? GL_FLOAT : GL_UNSIGNED_BYTE;
-
- if (cube_map) {
- for (int i = 0; i < 6; i++) {
- glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i,
- 0,
- internal_format,
- w,
- h,
- 0,
- GL_RGBA,
- type,
- cube_map[i]);
- }
- }
-
- if (GPU_get_mipmap() && mipmap) {
- glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
-
- if (ima) {
- ima->gpuflag |= IMA_GPU_MIPMAP_COMPLETE;
- }
- }
-
- gpu_del_cube_map(cube_map);
- }
- else {
- printf("Incorrect envmap size\n");
- }
- }
-
- glBindTexture(textarget, 0);
-
- if (ibuf) {
- IMB_freeImBuf(ibuf);
- }
-}
-
-/**
- * GPU_upload_dxt_texture() assumes that the texture is already bound and ready to go.
- * This is so the viewport and the BGE can share some code.
- * Returns false if the provided ImBuf doesn't have a supported DXT compression format
- */
-bool GPU_upload_dxt_texture(ImBuf *ibuf, bool use_srgb)
-{
-#ifdef WITH_DDS
- GLint format = 0;
- int blocksize, height, width, i, size, offset = 0;
-
- width = ibuf->x;
- height = ibuf->y;
-
- if (GLEW_EXT_texture_compression_s3tc) {
- if (ibuf->dds_data.fourcc == FOURCC_DXT1) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
- }
- else if (ibuf->dds_data.fourcc == FOURCC_DXT3) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
- }
- else if (ibuf->dds_data.fourcc == FOURCC_DXT5) {
- format = (use_srgb) ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT :
- GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
- }
- }
-
- if (format == 0) {
- fprintf(stderr, "Unable to find a suitable DXT compression, falling back to uncompressed\n");
- return false;
- }
-
- if (!is_power_of_2_resolution(width, height)) {
- fprintf(
- stderr,
- "Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
- return false;
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
-
- /* Reset to opengl Defaults. (Untested, might not be needed) */
- glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
-
- blocksize = (ibuf->dds_data.fourcc == FOURCC_DXT1) ? 8 : 16;
- for (i = 0; i < ibuf->dds_data.nummipmaps && (width || height); i++) {
- if (width == 0) {
- width = 1;
- }
- if (height == 0) {
- height = 1;
- }
-
- size = ((width + 3) / 4) * ((height + 3) / 4) * blocksize;
-
- glCompressedTexImage2D(
- GL_TEXTURE_2D, i, format, width, height, 0, size, ibuf->dds_data.data + offset);
-
- offset += size;
- width >>= 1;
- height >>= 1;
- }
- /* Restore Blender default. */
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- /* set number of mipmap levels we have, needed in case they don't go down to 1x1 */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1);
-
- return true;
-#else
- UNUSED_VARS(ibuf, use_srgb);
- return false;
-#endif
-}
-
-void GPU_create_gl_tex_compressed(unsigned int *bind, int textarget, Image *ima, ImBuf *ibuf)
-{
- /* For DDS we only support data, scene linear and sRGB. Converting to
- * different colorspace would break the compression. */
- const bool use_srgb = !(IMB_colormanagement_space_is_data(ibuf->rect_colorspace) ||
- IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
- const bool mipmap = GPU_get_mipmap();
- const bool half_float = (ibuf->flags & IB_halffloat) != 0;
-
-#ifndef WITH_DDS
- (void)ibuf;
- /* Fall back to uncompressed if DDS isn't enabled */
- GPU_create_gl_tex(
- bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
-#else
- glGenTextures(1, (GLuint *)bind);
- glBindTexture(textarget, *bind);
-
- if (textarget == GL_TEXTURE_2D && GPU_upload_dxt_texture(ibuf, use_srgb) == 0) {
- glDeleteTextures(1, (GLuint *)bind);
- GPU_create_gl_tex(
- bind, ibuf->rect, NULL, ibuf->x, ibuf->y, textarget, mipmap, half_float, use_srgb, ima);
- }
-
- glBindTexture(textarget, 0);
-#endif
-}
-
-/* these two functions are called on entering and exiting texture paint mode,
- * temporary disabling/enabling mipmapping on all images for quick texture
- * updates with glTexSubImage2D. images that didn't change don't have to be
- * re-uploaded to OpenGL */
-void GPU_paint_set_mipmap(Main *bmain, bool mipmap)
-{
-#ifndef GPU_STANDALONE
- if (!GTS.domipmap) {
- return;
- }
-
- GTS.texpaint = !mipmap;
-
- if (mipmap) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_has_opengl_texture(ima)) {
- if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
- for (int eye = 0; eye < 2; eye++) {
- for (int a = 0; a < TEXTARGET_COUNT; a++) {
- if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
- GPUTexture *tex = ima->gputexture[a][eye];
- if (tex != NULL) {
- GPU_texture_bind(tex, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gpu_get_mipmap_filter(0));
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
- GPU_texture_unbind(tex);
- }
- }
- }
- }
- }
- else {
- GPU_free_image(ima);
- }
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
- else {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_has_opengl_texture(ima)) {
- for (int eye = 0; eye < 2; eye++) {
- for (int a = 0; a < TEXTARGET_COUNT; a++) {
- if (ELEM(a, TEXTARGET_TEXTURE_2D, TEXTARGET_TEXTURE_2D_ARRAY)) {
- GPUTexture *tex = ima->gputexture[a][eye];
- if (tex != NULL) {
- GPU_texture_bind(tex, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gpu_get_mipmap_filter(1));
- GPU_texture_unbind(tex);
- }
- }
- }
- }
- }
- else {
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
- }
- }
- }
-#endif /* GPU_STANDALONE */
-}
-
-void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, int h)
-{
-#ifndef GPU_STANDALONE
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- ImageTile *tile = BKE_image_get_tile_from_iuser(ima, iuser);
-
- if ((ibuf == NULL) || (w == 0) || (h == 0)) {
- /* Full reload of texture. */
- GPU_free_image(ima);
- }
-
- GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
- /* Check if we need to update the main gputexture. */
- if (tex != NULL && tile == ima->tiles.first) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
- }
-
- /* Check if we need to update the array gputexture. */
- tex = ima->gputexture[TEXTARGET_TEXTURE_2D_ARRAY][0];
- if (tex != NULL) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
- }
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
-#endif
-}
-
-/* Delayed GPU texture free. Image datablocks can be deleted by any thread,
- * but there may not be any active OpenGL context. In that case we push them
- * into a queue and free the buffers later. */
-static LinkNode *gpu_texture_free_queue = NULL;
-static ThreadMutex gpu_texture_queue_mutex = BLI_MUTEX_INITIALIZER;
-
-static void gpu_free_unused_buffers()
-{
- if (gpu_texture_free_queue == NULL) {
- return;
- }
-
- BLI_mutex_lock(&gpu_texture_queue_mutex);
-
- if (gpu_texture_free_queue != NULL) {
- for (LinkNode *node = gpu_texture_free_queue; node; node = node->next) {
- GPUTexture *tex = node->link;
- GPU_texture_free(tex);
- }
-
- BLI_linklist_free(gpu_texture_free_queue, NULL);
- gpu_texture_free_queue = NULL;
- }
-
- BLI_mutex_unlock(&gpu_texture_queue_mutex);
-}
-
-static void gpu_free_image(Image *ima, const bool immediate)
-{
- for (int eye = 0; eye < 2; eye++) {
- for (int i = 0; i < TEXTARGET_COUNT; i++) {
- if (ima->gputexture[i][eye] != NULL) {
- if (immediate) {
- GPU_texture_free(ima->gputexture[i][eye]);
- }
- else {
- BLI_mutex_lock(&gpu_texture_queue_mutex);
- BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
- BLI_mutex_unlock(&gpu_texture_queue_mutex);
- }
-
- ima->gputexture[i][eye] = NULL;
- }
- }
- }
-
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
-}
-
-void GPU_free_unused_buffers()
-{
- if (BLI_thread_is_main()) {
- gpu_free_unused_buffers();
- }
-}
-
-void GPU_free_image(Image *ima)
-{
- gpu_free_image(ima, BLI_thread_is_main());
-}
-
-void GPU_free_images(Main *bmain)
-{
- if (bmain) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- GPU_free_image(ima);
- }
- }
-}
-
-/* same as above but only free animated images */
-void GPU_free_images_anim(Main *bmain)
-{
- if (bmain) {
- for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
- if (BKE_image_is_animated(ima)) {
- GPU_free_image(ima);
- }
- }
- }
-}
-
-void GPU_free_images_old(Main *bmain)
-{
- static int lasttime = 0;
- int ctime = (int)PIL_check_seconds_timer();
-
- /*
- * Run garbage collector once for every collecting period of time
- * if textimeout is 0, that's the option to NOT run the collector
- */
- if (U.textimeout == 0 || ctime % U.texcollectrate || ctime == lasttime) {
- return;
- }
-
- /* of course not! */
- if (G.is_rendering) {
- return;
- }
-
- lasttime = ctime;
-
- Image *ima = bmain->images.first;
- while (ima) {
- if ((ima->flag & IMA_NOCOLLECT) == 0 && ctime - ima->lastused > U.textimeout) {
- /* If it's in GL memory, deallocate and set time tag to current time
- * This gives textures a "second chance" to be used before dying. */
- if (BKE_image_has_opengl_texture(ima)) {
- GPU_free_image(ima);
- ima->lastused = ctime;
- }
- /* Otherwise, just kill the buffers */
- else {
- BKE_image_free_buffers(ima);
- }
- }
- ima = ima->id.next;
- }
-}
diff --git a/source/blender/gpu/intern/gpu_element.c b/source/blender/gpu/intern/gpu_element.cc
index 036588b4a48..449d119267d 100644
--- a/source/blender/gpu/intern/gpu_element.c
+++ b/source/blender/gpu/intern/gpu_element.cc
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "GPU_element.h"
+#include "GPU_glew.h"
#include "gpu_context_private.h"
@@ -37,21 +38,18 @@
static GLenum convert_index_type_to_gl(GPUIndexBufType type)
{
- static const GLenum table[] = {
- [GPU_INDEX_U16] = GL_UNSIGNED_SHORT,
- [GPU_INDEX_U32] = GL_UNSIGNED_INT,
- };
- return table[type];
+#if GPU_TRACK_INDEX_RANGE
+ return (type == GPU_INDEX_U32) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+#else
+ return GL_UNSIGNED_INT;
+#endif
}
uint GPU_indexbuf_size_get(const GPUIndexBuf *elem)
{
#if GPU_TRACK_INDEX_RANGE
- static const uint table[] = {
- [GPU_INDEX_U16] = sizeof(GLushort),
- [GPU_INDEX_U32] = sizeof(GLuint),
- };
- return elem->index_len * table[elem->index_type];
+ return elem->index_len *
+ ((elem->index_type == GPU_INDEX_U32) ? sizeof(GLuint) : sizeof(GLshort));
#else
return elem->index_len * sizeof(GLuint);
#endif
@@ -86,7 +84,7 @@ void GPU_indexbuf_init_ex(GPUIndexBufBuilder *builder,
builder->max_index_len = index_len;
builder->index_len = 0; // start empty
builder->prim_type = prim_type;
- builder->data = MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data");
+ builder->data = (uint *)MEM_callocN(builder->max_index_len * sizeof(uint), "GPUIndexBuf data");
}
void GPU_indexbuf_init(GPUIndexBufBuilder *builder,
@@ -241,7 +239,7 @@ void GPU_indexbuf_set_tri_restart(GPUIndexBufBuilder *builder, uint elem)
GPUIndexBuf *GPU_indexbuf_create_subrange(GPUIndexBuf *elem_src, uint start, uint length)
{
- GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
GPU_indexbuf_create_subrange_in_place(elem, elem_src, start, length);
return elem;
}
@@ -282,7 +280,7 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint
if (value == RESTART_INDEX) {
continue;
}
- else if (value < min_value) {
+ if (value < min_value) {
min_value = value;
}
else if (value > max_value) {
@@ -294,11 +292,10 @@ static uint index_range(const uint values[], uint value_len, uint *min_out, uint
*max_out = 0;
return 0;
}
- else {
- *min_out = min_value;
- *max_out = max_value;
- return max_value - min_value;
- }
+
+ *min_out = min_value;
+ *max_out = max_value;
+ return max_value - min_value;
}
static void squeeze_indices_short(GPUIndexBufBuilder *builder,
@@ -331,7 +328,7 @@ static void squeeze_indices_short(GPUIndexBufBuilder *builder,
GPUIndexBuf *GPU_indexbuf_build(GPUIndexBufBuilder *builder)
{
- GPUIndexBuf *elem = MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
+ GPUIndexBuf *elem = (GPUIndexBuf *)MEM_callocN(sizeof(GPUIndexBuf), "GPUIndexBuf");
GPU_indexbuf_build_in_place(builder, elem);
return elem;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.cc
index 9c37cc32e1d..35b70a18363 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.cc
@@ -31,6 +31,8 @@
#include "BKE_global.h"
#include "MEM_guardedalloc.h"
+#include "DNA_userdef_types.h"
+
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
@@ -104,7 +106,8 @@ static struct GPUGlobal {
static void gpu_detect_mip_render_workaround(void)
{
int cube_size = 2;
- float *source_pix = MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size, __func__);
+ float *source_pix = (float *)MEM_callocN(sizeof(float) * 4 * 6 * cube_size * cube_size,
+ __func__);
float clear_color[4] = {1.0f, 0.5f, 0.0f, 0.0f};
GPUTexture *tex = GPU_texture_create_cube(cube_size, GPU_RGBA16F, source_pix, NULL);
@@ -123,7 +126,7 @@ static void gpu_detect_mip_render_workaround(void)
GPU_framebuffer_restore();
GPU_framebuffer_free(fb);
- float *data = GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
+ float *data = (float *)GPU_texture_read(tex, GPU_DATA_FLOAT, 1);
GG.mip_render_workaround = !equals_v4v4(clear_color, data);
MEM_freeN(data);
@@ -238,6 +241,13 @@ bool GPU_crappy_amd_driver(void)
return GG.broken_amd_driver;
}
+int GPU_texture_size_with_limit(int res)
+{
+ int size = GPU_max_texture_size();
+ int reslimit = (U.glreslimit != 0) ? min_ii(U.glreslimit, size) : size;
+ return min_ii(reslimit, res);
+}
+
void gpu_extensions_init(void)
{
/* during 2.8 development each platform has its own OpenGL minimum requirements
@@ -311,7 +321,7 @@ void gpu_extensions_init(void)
if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_WIN, GPU_DRIVER_OFFICIAL)) {
/* Limit this fix to older hardware with GL < 4.5. This means Broadwell GPUs are
* covered since they only support GL 4.4 on windows.
- * This fixes some issues with workbench antialiasing on Win + Intel GPU. (see T76273) */
+ * This fixes some issues with workbench anti-aliasing on Win + Intel GPU. (see T76273) */
if (!GLEW_VERSION_4_5) {
GG.texture_copy_workaround = true;
}
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.cc
index 77abb786117..13df2268221 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -28,7 +28,6 @@
#include "BLI_utildefines.h"
#include "GPU_batch.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_shader.h"
@@ -53,6 +52,10 @@ typedef enum {
GPU_FB_MAX_ATTACHEMENT,
} GPUAttachmentType;
+#define FOREACH_ATTACHMENT_RANGE(att, _start, _end) \
+ for (GPUAttachmentType att = static_cast<GPUAttachmentType>(_start); att < _end; \
+ att = static_cast<GPUAttachmentType>(att + 1))
+
#define GPU_FB_MAX_COLOR_ATTACHMENT (GPU_FB_MAX_ATTACHEMENT - GPU_FB_COLOR_ATTACHMENT0)
#define GPU_FB_DIRTY_DRAWBUFFER (1 << 15)
@@ -74,17 +77,25 @@ struct GPUFrameBuffer {
static GLenum convert_attachment_type_to_gl(GPUAttachmentType type)
{
- static const GLenum table[] = {
- [GPU_FB_DEPTH_ATTACHMENT] = GL_DEPTH_ATTACHMENT,
- [GPU_FB_DEPTH_STENCIL_ATTACHMENT] = GL_DEPTH_STENCIL_ATTACHMENT,
- [GPU_FB_COLOR_ATTACHMENT0] = GL_COLOR_ATTACHMENT0,
- [GPU_FB_COLOR_ATTACHMENT1] = GL_COLOR_ATTACHMENT1,
- [GPU_FB_COLOR_ATTACHMENT2] = GL_COLOR_ATTACHMENT2,
- [GPU_FB_COLOR_ATTACHMENT3] = GL_COLOR_ATTACHMENT3,
- [GPU_FB_COLOR_ATTACHMENT4] = GL_COLOR_ATTACHMENT4,
- [GPU_FB_COLOR_ATTACHMENT5] = GL_COLOR_ATTACHMENT5,
- };
- return table[type];
+#define ATTACHMENT(type) \
+ case GPU_FB_##type: { \
+ return GL_##type; \
+ } \
+ ((void)0)
+
+ switch (type) {
+ ATTACHMENT(DEPTH_ATTACHMENT);
+ ATTACHMENT(DEPTH_STENCIL_ATTACHMENT);
+ ATTACHMENT(COLOR_ATTACHMENT0);
+ ATTACHMENT(COLOR_ATTACHMENT1);
+ ATTACHMENT(COLOR_ATTACHMENT2);
+ ATTACHMENT(COLOR_ATTACHMENT3);
+ ATTACHMENT(COLOR_ATTACHMENT4);
+ ATTACHMENT(COLOR_ATTACHMENT5);
+ default:
+ BLI_assert(0);
+ return GL_COLOR_ATTACHMENT0;
+ }
}
static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot)
@@ -98,7 +109,7 @@ static GPUAttachmentType attachment_type_from_tex(GPUTexture *tex, int slot)
case GPU_DEPTH32F_STENCIL8:
return GPU_FB_DEPTH_STENCIL_ATTACHMENT;
default:
- return GPU_FB_COLOR_ATTACHMENT0 + slot;
+ return static_cast<GPUAttachmentType>(GPU_FB_COLOR_ATTACHMENT0 + slot);
}
}
@@ -116,9 +127,8 @@ static GPUTexture *framebuffer_get_depth_tex(GPUFrameBuffer *fb)
if (fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex) {
return fb->attachments[GPU_FB_DEPTH_ATTACHMENT].tex;
}
- else {
- return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex;
- }
+
+ return fb->attachments[GPU_FB_DEPTH_STENCIL_ATTACHMENT].tex;
}
static GPUTexture *framebuffer_get_color_tex(GPUFrameBuffer *fb, int slot)
@@ -179,9 +189,8 @@ GPUFrameBuffer *GPU_framebuffer_active_get(void)
if (ctx) {
return gpu_context_active_framebuffer_get(ctx);
}
- else {
- return 0;
- }
+
+ return 0;
}
static void gpu_framebuffer_current_set(GPUFrameBuffer *fb)
@@ -198,7 +207,7 @@ GPUFrameBuffer *GPU_framebuffer_create(void)
{
/* We generate the FB object later at first use in order to
* create the framebuffer in the right opengl context. */
- return MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
+ return (GPUFrameBuffer *)MEM_callocN(sizeof(GPUFrameBuffer), "GPUFrameBuffer");
}
static void gpu_framebuffer_init(GPUFrameBuffer *fb)
@@ -210,7 +219,8 @@ static void gpu_framebuffer_init(GPUFrameBuffer *fb)
void GPU_framebuffer_free(GPUFrameBuffer *fb)
{
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
GPU_framebuffer_texture_detach(fb, fb->attachments[type].tex);
}
@@ -249,7 +259,7 @@ static void gpu_framebuffer_texture_attach_ex(
if ((attachment->tex == tex) && (attachment->mip == mip) && (attachment->layer == layer)) {
return; /* Exact same texture already bound here. */
}
- else if (attachment->tex != NULL) {
+ if (attachment->tex != NULL) {
GPU_framebuffer_texture_detach(fb, attachment->tex);
}
@@ -304,7 +314,7 @@ void GPU_framebuffer_texture_detach_slot(GPUFrameBuffer *fb, GPUTexture *tex, in
void GPU_framebuffer_texture_detach(GPUFrameBuffer *fb, GPUTexture *tex)
{
- GPUAttachmentType type = GPU_texture_detach_framebuffer(tex, fb);
+ GPUAttachmentType type = (GPUAttachmentType)GPU_texture_detach_framebuffer(tex, fb);
GPU_framebuffer_texture_detach_slot(fb, tex, type);
}
@@ -387,8 +397,8 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb)
BLI_assert(GPU_framebuffer_active_get() == fb);
/* Update attachments */
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
-
+ FOREACH_ATTACHMENT_RANGE(type, 0, GPU_FB_MAX_ATTACHEMENT)
+ {
if (type >= GPU_FB_COLOR_ATTACHMENT0) {
if (fb->attachments[type].tex) {
gl_attachments[numslots] = convert_attachment_type_to_gl(type);
@@ -402,7 +412,7 @@ static void gpu_framebuffer_update_attachments(GPUFrameBuffer *fb)
if (GPU_FB_ATTACHEMENT_IS_DIRTY(fb->dirty_flag, type) == false) {
continue;
}
- else if (fb->attachments[type].tex != NULL) {
+ if (fb->attachments[type].tex != NULL) {
gpu_framebuffer_attachment_attach(&fb->attachments[type], type);
fb->multisample = (GPU_texture_samples(fb->attachments[type].tex) > 0);
@@ -438,7 +448,8 @@ static void gpu_framebuffer_update_attachments_and_fill_empty_slots(GPUFrameBuff
BLI_assert(GPU_framebuffer_active_get() == fb);
/* Update attachments */
- for (GPUAttachmentType type = GPU_FB_MAX_ATTACHEMENT; type--;) {
+ for (int i_type = GPU_FB_MAX_ATTACHEMENT - 1; i_type >= 0; --i_type) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
GPUTexture *tex = fb->attachments[type].tex;
if (type >= GPU_FB_COLOR_ATTACHMENT0) {
@@ -623,8 +634,9 @@ void GPU_framebuffer_multi_clear(GPUFrameBuffer *fb, const float (*clear_cols)[4
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
- GPUAttachmentType type = GPU_FB_COLOR_ATTACHMENT0;
- for (int i = 0; type < GPU_FB_MAX_ATTACHEMENT; i++, type++) {
+ int i_type = GPU_FB_COLOR_ATTACHMENT0;
+ for (int i = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i++, i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
glClearBufferfv(GL_COLOR, i, clear_cols[i]);
}
@@ -702,7 +714,8 @@ void GPU_framebuffer_read_color(GPUFrameBuffer *fb,
void *data)
{
CHECK_FRAMEBUFFER_IS_BOUND(fb);
- gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, data);
+ gpu_framebuffer_read_color_ex(
+ x, y, w, h, channels, GL_COLOR_ATTACHMENT0 + slot, format, (float *)data);
}
/* read_slot and write_slot are only used for color buffers. */
@@ -815,7 +828,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
current_dim[0] = max_ii(current_dim[0] / 2, 1);
current_dim[1] = max_ii(current_dim[1] / 2, 1);
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
/* Some Intel HDXXX have issue with rendering to a mipmap that is below
* the texture GL_TEXTURE_MAX_LEVEL. So even if it not correct, in this case
@@ -844,7 +858,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
}
}
- for (GPUAttachmentType type = 0; type < GPU_FB_MAX_ATTACHEMENT; type++) {
+ for (int i_type = 0; i_type < GPU_FB_MAX_ATTACHEMENT; i_type++) {
+ GPUAttachmentType type = static_cast<GPUAttachmentType>(i_type);
if (fb->attachments[type].tex != NULL) {
/* reset mipmap level range */
GPUTexture *tex = fb->attachments[type].tex;
@@ -885,9 +900,11 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
for (int i = 0; i < MAX_CTX_FB_LEN; i++) {
if (ofs->framebuffers[i].fb == NULL) {
ofs->framebuffers[i].ctx = ctx;
- GPU_framebuffer_ensure_config(
- &ofs->framebuffers[i].fb,
- {GPU_ATTACHMENT_TEXTURE(ofs->depth), GPU_ATTACHMENT_TEXTURE(ofs->color)});
+ GPU_framebuffer_ensure_config(&ofs->framebuffers[i].fb,
+ {
+ GPU_ATTACHMENT_TEXTURE(ofs->depth),
+ GPU_ATTACHMENT_TEXTURE(ofs->color),
+ });
}
if (ofs->framebuffers[i].ctx == ctx) {
@@ -916,9 +933,7 @@ static GPUFrameBuffer *gpu_offscreen_fb_get(GPUOffScreen *ofs)
GPUOffScreen *GPU_offscreen_create(
int width, int height, bool depth, bool high_bitdepth, char err_out[256])
{
- GPUOffScreen *ofs;
-
- ofs = MEM_callocN(sizeof(GPUOffScreen), "GPUOffScreen");
+ GPUOffScreen *ofs = (GPUOffScreen *)MEM_callocN(sizeof(GPUOffScreen), __func__);
/* Sometimes areas can have 0 height or width and this will
* create a 1D texture which we don't want. */
@@ -975,7 +990,7 @@ void GPU_offscreen_free(GPUOffScreen *ofs)
void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
{
if (save) {
- gpuPushAttr(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT);
+ gpuPushAttr((eGPUAttrMask)(GPU_SCISSOR_BIT | GPU_VIEWPORT_BIT));
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
gpuPushFrameBuffer(fb);
}
@@ -1023,14 +1038,15 @@ void GPU_offscreen_draw_to_screen(GPUOffScreen *ofs, int x, int y)
glBindFramebuffer(GL_READ_FRAMEBUFFER, GPU_framebuffer_default());
}
-void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
+void GPU_offscreen_read_pixels(GPUOffScreen *ofs, eGPUDataFormat type, void *pixels)
{
const int w = GPU_texture_width(ofs->color);
const int h = GPU_texture_height(ofs->color);
- BLI_assert(type == GL_UNSIGNED_BYTE || type == GL_FLOAT);
+ BLI_assert(ELEM(type, GPU_DATA_UNSIGNED_BYTE, GPU_DATA_FLOAT));
+ GLenum gl_type = (type == GPU_DATA_FLOAT) ? GL_FLOAT : GL_UNSIGNED_BYTE;
- glReadPixels(0, 0, w, h, GL_RGBA, type, pixels);
+ glReadPixels(0, 0, w, h, GL_RGBA, gl_type, pixels);
}
int GPU_offscreen_width(const GPUOffScreen *ofs)
@@ -1077,8 +1093,7 @@ void GPU_clear(eGPUFrameBufferBits flags)
void GPU_frontbuffer_read_pixels(
int x, int y, int w, int h, int channels, eGPUDataFormat format, void *data)
{
- glReadBuffer(GL_FRONT);
- gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, data);
+ gpu_framebuffer_read_color_ex(x, y, w, h, channels, GL_FRONT, format, (float *)data);
}
/* For stereo rendering. */
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.cc
index 1e99371f9a1..7283f7c12aa 100644
--- a/source/blender/gpu/intern/gpu_immediate.c
+++ b/source/blender/gpu/intern/gpu_immediate.cc
@@ -29,6 +29,7 @@
#include "GPU_attr_binding.h"
#include "GPU_immediate.h"
+#include "GPU_matrix.h"
#include "GPU_texture.h"
#include "gpu_attr_binding_private.h"
@@ -40,10 +41,6 @@
#include <stdlib.h>
#include <string.h>
-/* necessary functions from matrix API */
-extern void GPU_matrix_bind(const GPUShaderInterface *);
-extern bool GPU_matrix_dirty_get(void);
-
typedef struct ImmediateDrawBuffer {
GLuint vbo_id;
GLubyte *buffer_data;
@@ -75,7 +72,7 @@ typedef struct {
GLuint vao_id;
- GLuint bound_program;
+ GPUShader *bound_program;
const GPUShaderInterface *shader_interface;
GPUAttrBinding attr_binding;
uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */
@@ -146,48 +143,47 @@ GPUVertFormat *immVertexFormat(void)
return &imm.vertex_format;
}
-void immBindProgram(GLuint program, const GPUShaderInterface *shaderface)
+void immBindShader(GPUShader *shader)
{
#if TRUST_NO_ONE
- assert(imm.bound_program == 0);
- assert(glIsProgram(program));
+ assert(imm.bound_program == NULL);
+ assert(glIsProgram(shader->program));
#endif
- imm.bound_program = program;
- imm.shader_interface = shaderface;
+ imm.bound_program = shader;
+ imm.shader_interface = shader->interface;
if (!imm.vertex_format.packed) {
VertexFormat_pack(&imm.vertex_format);
}
- glUseProgram(program);
- get_attr_locations(&imm.vertex_format, &imm.attr_binding, shaderface);
- GPU_matrix_bind(shaderface);
- GPU_shader_set_srgb_uniform(shaderface);
+ GPU_shader_bind(shader);
+ get_attr_locations(&imm.vertex_format, &imm.attr_binding, imm.shader_interface);
+ GPU_matrix_bind(imm.shader_interface);
+ GPU_shader_set_srgb_uniform(imm.shader_interface);
}
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
{
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
- immBindProgram(shader->program, shader->interface);
+ immBindShader(shader);
}
void immUnbindProgram(void)
{
#if TRUST_NO_ONE
- assert(imm.bound_program != 0);
+ assert(imm.bound_program != NULL);
#endif
#if PROGRAM_NO_OPTI
glUseProgram(0);
#endif
- imm.bound_program = 0;
+ imm.bound_program = NULL;
}
/* XXX do not use it. Special hack to use OCIO with batch API. */
-void immGetProgram(GLuint *program, GPUShaderInterface **shaderface)
+GPUShader *immGetShader(void)
{
- *program = imm.bound_program;
- *shaderface = (GPUShaderInterface *)imm.shader_interface;
+ return imm.bound_program;
}
#if TRUST_NO_ONE
@@ -281,7 +277,7 @@ void immBegin(GPUPrimType prim_type, uint vertex_len)
}
#endif
- active_buffer->buffer_data = glMapBufferRange(
+ active_buffer->buffer_data = (GLubyte *)glMapBufferRange(
GL_ARRAY_BUFFER,
active_buffer->buffer_offset,
bytes_needed,
@@ -367,17 +363,18 @@ static void immDrawSetup(void)
const GLvoid *pointer = (const GLubyte *)0 + offset;
const uint loc = read_attr_location(&imm.attr_binding, a_idx);
+ const GLenum type = convert_comp_type_to_gl(static_cast<GPUVertCompType>(a->comp_type));
switch (a->fetch_mode) {
case GPU_FETCH_FLOAT:
case GPU_FETCH_INT_TO_FLOAT:
- glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_FALSE, stride, pointer);
+ glVertexAttribPointer(loc, a->comp_len, type, GL_FALSE, stride, pointer);
break;
case GPU_FETCH_INT_TO_FLOAT_UNIT:
- glVertexAttribPointer(loc, a->comp_len, a->gl_comp_type, GL_TRUE, stride, pointer);
+ glVertexAttribPointer(loc, a->comp_len, type, GL_TRUE, stride, pointer);
break;
case GPU_FETCH_INT:
- glVertexAttribIPointer(loc, a->comp_len, a->gl_comp_type, stride, pointer);
+ glVertexAttribIPointer(loc, a->comp_len, type, stride, pointer);
}
}
@@ -425,7 +422,7 @@ void immEnd(void)
GPU_vertbuf_data_resize(imm.batch->verts[0], imm.vertex_len);
/* TODO: resize only if vertex count is much smaller */
}
- GPU_batch_program_set(imm.batch, imm.bound_program, imm.shader_interface);
+ GPU_batch_set_shader(imm.batch, imm.bound_program);
imm.batch->phase = GPU_BATCH_READY_TO_DRAW;
imm.batch = NULL; /* don't free, batch belongs to caller */
}
diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c
index e834d6afccb..b8cd9fe356d 100644
--- a/source/blender/gpu/intern/gpu_immediate_util.c
+++ b/source/blender/gpu/intern/gpu_immediate_util.c
@@ -460,10 +460,10 @@ void imm_draw_cylinder_fill_normal_3d(
float h1 = height * ((float)j / (float)stacks);
float h2 = height * ((float)(j + 1) / (float)stacks);
- float v1[3] = {r1 * cos2, r1 * sin2, h1};
- float v2[3] = {r2 * cos2, r2 * sin2, h2};
- float v3[3] = {r2 * cos1, r2 * sin1, h2};
- float v4[3] = {r1 * cos1, r1 * sin1, h1};
+ const float v1[3] = {r1 * cos2, r1 * sin2, h1};
+ const float v2[3] = {r2 * cos2, r2 * sin2, h2};
+ const float v3[3] = {r2 * cos1, r2 * sin1, h2};
+ const float v4[3] = {r1 * cos1, r1 * sin1, h1};
float n1[3], n2[3];
/* calc normals */
@@ -516,10 +516,10 @@ void imm_draw_cylinder_wire_3d(
float h1 = height * ((float)j / (float)stacks);
float h2 = height * ((float)(j + 1) / (float)stacks);
- float v1[3] = {r1 * cos2, r1 * sin2, h1};
- float v2[3] = {r2 * cos2, r2 * sin2, h2};
- float v3[3] = {r2 * cos1, r2 * sin1, h2};
- float v4[3] = {r1 * cos1, r1 * sin1, h1};
+ const float v1[3] = {r1 * cos2, r1 * sin2, h1};
+ const float v2[3] = {r2 * cos2, r2 * sin2, h2};
+ const float v3[3] = {r2 * cos1, r2 * sin1, h2};
+ const float v4[3] = {r1 * cos1, r1 * sin1, h1};
immVertex3fv(pos, v1);
immVertex3fv(pos, v2);
@@ -554,10 +554,10 @@ void imm_draw_cylinder_fill_3d(
float h1 = height * ((float)j / (float)stacks);
float h2 = height * ((float)(j + 1) / (float)stacks);
- float v1[3] = {r1 * cos2, r1 * sin2, h1};
- float v2[3] = {r2 * cos2, r2 * sin2, h2};
- float v3[3] = {r2 * cos1, r2 * sin1, h2};
- float v4[3] = {r1 * cos1, r1 * sin1, h1};
+ const float v1[3] = {r1 * cos2, r1 * sin2, h1};
+ const float v2[3] = {r2 * cos2, r2 * sin2, h2};
+ const float v3[3] = {r2 * cos1, r2 * sin1, h2};
+ const float v4[3] = {r1 * cos1, r1 * sin1, h1};
/* first tri */
immVertex3fv(pos, v1);
diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c
index 54ddb9351b9..c5061ec9ba3 100644
--- a/source/blender/gpu/intern/gpu_init_exit.c
+++ b/source/blender/gpu/intern/gpu_init_exit.c
@@ -95,7 +95,7 @@ void GPU_exit(void)
initialized = false;
}
-bool GPU_is_initialized(void)
+bool GPU_is_init(void)
{
return initialized;
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index c65c1046b8f..8d2003591e4 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -85,7 +85,7 @@ struct GPUMaterial {
bool has_surface_output;
/* Only used by Eevee to know which bsdf are used. */
- int flag;
+ eGPUMatFlag flag;
/* Used by 2.8 pipeline */
GPUUniformBuffer *ubo; /* UBOs for shader uniforms. */
@@ -311,12 +311,11 @@ static float eval_profile(float r, short falloff_type, float sharpness, float pa
if (falloff_type == SHD_SUBSURFACE_BURLEY || falloff_type == SHD_SUBSURFACE_RANDOM_WALK) {
return burley_profile(r, param) / BURLEY_TRUNCATE_CDF;
}
- else if (falloff_type == SHD_SUBSURFACE_CUBIC) {
+ if (falloff_type == SHD_SUBSURFACE_CUBIC) {
return cubic_profile(r, param, sharpness);
}
- else {
- return gaussian_profile(r, param);
- }
+
+ return gaussian_profile(r, param);
}
/* Resolution for each sample of the precomputed kernel profile */
@@ -659,7 +658,8 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
const char *geom_code,
const char *frag_lib,
const char *defines,
- const char *name)
+ const char *name,
+ GPUMaterialEvalCallbackFn callback)
{
LinkData *link;
bool has_volume_output, has_surface_output;
@@ -696,6 +696,9 @@ GPUMaterial *GPU_material_from_nodetree(Scene *scene,
mat->has_volume_output = has_volume_output;
if (mat->graph.outlink) {
+ if (callback) {
+ callback(mat, options, &vert_code, &geom_code, &frag_lib, &defines);
+ }
/* HACK: this is only for eevee. We add the define here after the nodetree evaluation. */
if (GPU_material_flag_get(mat, GPU_MATFLAG_SSS)) {
defines = BLI_string_joinN(defines,
diff --git a/source/blender/gpu/intern/gpu_material_library.c b/source/blender/gpu/intern/gpu_material_library.c
index 42cd9673ac2..e0165e1fa83 100644
--- a/source/blender/gpu/intern/gpu_material_library.c
+++ b/source/blender/gpu/intern/gpu_material_library.c
@@ -678,14 +678,13 @@ char *gpu_str_skip_token(char *str, char *token, int max)
if (ELEM(*str, ' ', '(', ')', ',', ';', '\t', '\n', '\r')) {
break;
}
- else {
- if (token && len < max - 1) {
- *token = *str;
- token++;
- len++;
- }
- str++;
+
+ if (token && len < max - 1) {
+ *token = *str;
+ token++;
+ len++;
}
+ str++;
}
if (token) {
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.cc
index 669bf56b726..4174f498402 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.cc
@@ -37,8 +37,6 @@
#include "MEM_guardedalloc.h"
-#define DEBUG_MATRIX_BIND 0
-
#define MATRIX_STACK_DEPTH 32
typedef float Mat4[4][4];
@@ -79,7 +77,7 @@ GPUMatrixState *GPU_matrix_state_create(void)
} \
}
- GPUMatrixState *state = MEM_mallocN(sizeof(*state), __func__);
+ GPUMatrixState *state = (GPUMatrixState *)MEM_mallocN(sizeof(*state), __func__);
const MatrixStack identity_stack = {{MATRIX_4X4_IDENTITY}, 0};
state->model_view_stack = state->projection_stack = identity_stack;
@@ -592,9 +590,8 @@ const float (*GPU_matrix_model_view_get(float m[4][4]))[4]
copy_m4_m4(m, ModelView);
return m;
}
- else {
- return ModelView;
- }
+
+ return ModelView;
}
const float (*GPU_matrix_projection_get(float m[4][4]))[4]
@@ -603,9 +600,8 @@ const float (*GPU_matrix_projection_get(float m[4][4]))[4]
copy_m4_m4(m, Projection);
return m;
}
- else {
- return Projection;
- }
+
+ return Projection;
}
const float (*GPU_matrix_model_view_projection_get(float m[4][4]))[4]
@@ -662,51 +658,32 @@ void GPU_matrix_bind(const GPUShaderInterface *shaderface)
int32_t MV_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_MODELVIEW_INV);
int32_t P_inv = GPU_shaderinterface_uniform_builtin(shaderface, GPU_UNIFORM_PROJECTION_INV);
+ /* XXX(fclem) this works but this assumes shader is unused inside GPU_shader_uniform_vector. */
+ GPUShader *sh = NULL;
if (MV != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting MV matrix");
-#endif
-
- glUniformMatrix4fv(MV, 1, GL_FALSE, (const float *)GPU_matrix_model_view_get(NULL));
+ GPU_shader_uniform_vector(sh, MV, 16, 1, (const float *)GPU_matrix_model_view_get(NULL));
}
-
if (P != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting P matrix");
-#endif
-
- glUniformMatrix4fv(P, 1, GL_FALSE, (const float *)GPU_matrix_projection_get(NULL));
+ GPU_shader_uniform_vector(sh, P, 16, 1, (const float *)GPU_matrix_projection_get(NULL));
}
-
if (MVP != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting MVP matrix");
-#endif
-
- glUniformMatrix4fv(
- MVP, 1, GL_FALSE, (const float *)GPU_matrix_model_view_projection_get(NULL));
+ GPU_shader_uniform_vector(
+ sh, MVP, 16, 1, (const float *)GPU_matrix_model_view_projection_get(NULL));
}
-
if (N != -1) {
-#if DEBUG_MATRIX_BIND
- puts("setting normal matrix");
-#endif
-
- glUniformMatrix3fv(N, 1, GL_FALSE, (const float *)GPU_matrix_normal_get(NULL));
+ GPU_shader_uniform_vector(sh, N, 9, 1, (const float *)GPU_matrix_normal_get(NULL));
}
-
if (MV_inv != -1) {
Mat4 m;
GPU_matrix_model_view_get(m);
invert_m4(m);
- glUniformMatrix4fv(MV_inv, 1, GL_FALSE, (const float *)m);
+ GPU_shader_uniform_vector(sh, MV_inv, 16, 1, (const float *)m);
}
-
if (P_inv != -1) {
Mat4 m;
GPU_matrix_projection_get(m);
invert_m4(m);
- glUniformMatrix4fv(P_inv, 1, GL_FALSE, (const float *)m);
+ GPU_shader_uniform_vector(sh, P_inv, 16, 1, (const float *)m);
}
gpu_matrix_state_active_set_dirty(false);
diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h
index 21bb139f610..7265abf4d65 100644
--- a/source/blender/gpu/intern/gpu_node_graph.h
+++ b/source/blender/gpu/intern/gpu_node_graph.h
@@ -28,7 +28,6 @@
#include "DNA_customdata_types.h"
#include "DNA_listBase.h"
-#include "GPU_glew.h"
#include "GPU_material.h"
#include "GPU_shader.h"
diff --git a/source/blender/gpu/intern/gpu_platform.c b/source/blender/gpu/intern/gpu_platform.cc
index 5cabde61bc3..5cabde61bc3 100644
--- a/source/blender/gpu/intern/gpu_platform.c
+++ b/source/blender/gpu/intern/gpu_platform.cc
diff --git a/source/blender/gpu/intern/gpu_primitive.c b/source/blender/gpu/intern/gpu_primitive.c
index 2285c1ab95b..3b11b38db87 100644
--- a/source/blender/gpu/intern/gpu_primitive.c
+++ b/source/blender/gpu/intern/gpu_primitive.c
@@ -26,35 +26,6 @@
#include "GPU_primitive.h"
#include "gpu_primitive_private.h"
-GPUPrimClass GPU_primtype_class(GPUPrimType prim_type)
-{
- static const GPUPrimClass classes[] = {
- [GPU_PRIM_POINTS] = GPU_PRIM_CLASS_POINT,
- [GPU_PRIM_LINES] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_STRIP] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_LOOP] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_TRIS] = GPU_PRIM_CLASS_SURFACE,
- [GPU_PRIM_TRI_STRIP] = GPU_PRIM_CLASS_SURFACE,
- [GPU_PRIM_TRI_FAN] = GPU_PRIM_CLASS_SURFACE,
-
- [GPU_PRIM_LINES_ADJ] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_LINE_STRIP_ADJ] = GPU_PRIM_CLASS_LINE,
- [GPU_PRIM_TRIS_ADJ] = GPU_PRIM_CLASS_SURFACE,
-
- [GPU_PRIM_NONE] = GPU_PRIM_CLASS_NONE,
- };
-
- return classes[prim_type];
-}
-
-bool GPU_primtype_belongs_to_class(GPUPrimType prim_type, GPUPrimClass prim_class)
-{
- if (prim_class == GPU_PRIM_CLASS_NONE && prim_type == GPU_PRIM_NONE) {
- return true;
- }
- return prim_class & GPU_primtype_class(prim_type);
-}
-
GLenum convert_prim_type_to_gl(GPUPrimType prim_type)
{
#if TRUST_NO_ONE
diff --git a/source/blender/gpu/intern/gpu_primitive_private.h b/source/blender/gpu/intern/gpu_primitive_private.h
index b3b6bd7fc88..e91eec18786 100644
--- a/source/blender/gpu/intern/gpu_primitive_private.h
+++ b/source/blender/gpu/intern/gpu_primitive_private.h
@@ -25,4 +25,13 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO(fclem) move to OGL backend */
GLenum convert_prim_type_to_gl(GPUPrimType);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_private.h b/source/blender/gpu/intern/gpu_private.h
index a5caa816ef4..ef96bedae4a 100644
--- a/source/blender/gpu/intern/gpu_private.h
+++ b/source/blender/gpu/intern/gpu_private.h
@@ -20,6 +20,10 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* call this before running any of the functions below */
void gpu_platform_init(void);
void gpu_platform_exit(void);
@@ -39,3 +43,7 @@ void gpu_framebuffer_module_exit(void);
/* gpu_pbvh.c */
void gpu_pbvh_init(void);
void gpu_pbvh_exit(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 5766a176a96..c069cbe012f 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <string.h>
-#include "GPU_glew.h"
#include "GPU_select.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c
index c6d8545527c..0f6f29fab40 100644
--- a/source/blender/gpu/intern/gpu_select_pick.c
+++ b/source/blender/gpu/intern/gpu_select_pick.c
@@ -27,7 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#include "GPU_draw.h"
#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_select.h"
@@ -205,12 +204,11 @@ static int depth_id_cmp(const void *v1, const void *v2)
if (d1->id < d2->id) {
return -1;
}
- else if (d1->id > d2->id) {
+ if (d1->id > d2->id) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int depth_cmp(const void *v1, const void *v2)
@@ -219,12 +217,11 @@ static int depth_cmp(const void *v1, const void *v2)
if (d1->depth < d2->depth) {
return -1;
}
- else if (d1->depth > d2->depth) {
+ if (d1->depth > d2->depth) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
/* depth sorting */
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index 70ad2f6759e..f67c9c36a6b 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -147,9 +147,8 @@ bool gpu_select_query_load_id(uint id)
g_query_state.index++;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
}
diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc
new file mode 100644
index 00000000000..76c439b86b5
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_shader.cc
@@ -0,0 +1,838 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math_base.h"
+#include "BLI_math_vector.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_appdir.h"
+#include "BKE_global.h"
+
+#include "DNA_space_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_matrix.h"
+#include "GPU_platform.h"
+#include "GPU_shader.h"
+#include "GPU_texture.h"
+#include "GPU_uniformbuffer.h"
+
+#include "gpu_shader_private.h"
+
+extern "C" char datatoc_gpu_shader_colorspace_lib_glsl[];
+
+/* Adjust these constants as needed. */
+#define MAX_DEFINE_LENGTH 256
+#define MAX_EXT_DEFINE_LENGTH 512
+
+#ifndef NDEBUG
+static uint g_shaderid = 0;
+#endif
+
+/* -------------------------------------------------------------------- */
+/** \name Convenience functions
+ * \{ */
+
+static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
+{
+ int line = 1;
+
+ fprintf(stderr, "GPUShader: %s error:\n", task);
+
+ for (int i = 0; i < totcode; i++) {
+ const char *c, *pos, *end = code[i] + strlen(code[i]);
+
+ if (G.debug & G_DEBUG) {
+ fprintf(stderr, "===== shader string %d ====\n", i + 1);
+
+ c = code[i];
+ while ((c < end) && (pos = strchr(c, '\n'))) {
+ fprintf(stderr, "%2d ", line);
+ fwrite(c, (pos + 1) - c, 1, stderr);
+ c = pos + 1;
+ line++;
+ }
+
+ fprintf(stderr, "%s", c);
+ }
+ }
+
+ fprintf(stderr, "%s\n", log);
+}
+
+static const char *gpu_shader_version(void)
+{
+ return "#version 330\n";
+}
+
+static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
+{
+ /* enable extensions for features that are not part of our base GLSL version
+ * don't use an extension for something already available!
+ */
+
+ if (GLEW_ARB_texture_gather) {
+ /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
+ * is reported to be supported but yield a compile error (see T55802). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
+ strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
+
+ /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
+ * shader so double check the preprocessor define (see T56544). */
+ if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
+ strcat(defines, "#ifdef GL_ARB_texture_gather\n");
+ strcat(defines, "# define GPU_ARB_texture_gather\n");
+ strcat(defines, "#endif\n");
+ }
+ else {
+ strcat(defines, "#define GPU_ARB_texture_gather\n");
+ }
+ }
+ }
+ if (GLEW_ARB_texture_query_lod) {
+ /* a #version 400 feature, but we use #version 330 maximum so use extension */
+ strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
+ }
+ if (GLEW_ARB_shader_draw_parameters) {
+ strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
+ }
+ if (GPU_arb_texture_cube_map_array_is_supported()) {
+ strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
+ strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
+ }
+}
+
+static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
+{
+ /* some useful defines to detect GPU type */
+ if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_ATI\n");
+ if (GPU_crappy_amd_driver()) {
+ strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n");
+ }
+ }
+ else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_NVIDIA\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define GPU_INTEL\n");
+ }
+
+ /* some useful defines to detect OS type */
+ if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_WIN\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_MAC\n");
+ }
+ else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
+ strcat(defines, "#define OS_UNIX\n");
+ }
+
+ float derivatives_factors[2];
+ GPU_get_dfdy_factors(derivatives_factors);
+ if (derivatives_factors[0] == 1.0f) {
+ strcat(defines, "#define DFDX_SIGN 1.0\n");
+ }
+ else {
+ strcat(defines, "#define DFDX_SIGN -1.0\n");
+ }
+
+ if (derivatives_factors[1] == 1.0f) {
+ strcat(defines, "#define DFDY_SIGN 1.0\n");
+ }
+ else {
+ strcat(defines, "#define DFDY_SIGN -1.0\n");
+ }
+}
+
+#define DEBUG_SHADER_NONE ""
+#define DEBUG_SHADER_VERTEX "vert"
+#define DEBUG_SHADER_FRAGMENT "frag"
+#define DEBUG_SHADER_GEOMETRY "geom"
+
+/**
+ * Dump GLSL shaders to disk
+ *
+ * This is used for profiling shader performance externally and debug if shader code is correct.
+ * If called with no code, it simply bumps the shader index, so different shaders for the same
+ * program share the same index.
+ */
+static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
+{
+ if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
+ return;
+ }
+
+ /* We use the same shader index for shaders in the same program.
+ * So we call this function once before calling for the individual shaders. */
+ static int shader_index = 0;
+ if (code == NULL) {
+ shader_index++;
+ BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
+ return;
+ }
+
+ /* Determine the full path of the new shader. */
+ char shader_path[FILE_MAX];
+
+ char file_name[512] = {'\0'};
+ sprintf(file_name, "%04d.%s", shader_index, extension);
+
+ BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
+
+ /* Write shader to disk. */
+ FILE *f = fopen(shader_path, "w");
+ if (f == NULL) {
+ printf("Error writing to file: %s\n", shader_path);
+ }
+ for (int j = 0; j < num_shaders; j++) {
+ fprintf(f, "%s", code[j]);
+ }
+ fclose(f);
+ printf("Shader file written to disk: %s\n", shader_path);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Creation / Destruction
+ * \{ */
+
+GPUShader *GPU_shader_create(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const char *shname)
+{
+ return GPU_shader_create_ex(
+ vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
+}
+
+GPUShader *GPU_shader_create_from_python(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines)
+{
+ char *libcodecat = NULL;
+
+ if (libcode == NULL) {
+ libcode = datatoc_gpu_shader_colorspace_lib_glsl;
+ }
+ else {
+ libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
+ }
+
+ GPUShader *sh = GPU_shader_create_ex(
+ vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
+
+ MEM_SAFE_FREE(libcodecat);
+ return sh;
+}
+
+GPUShader *GPU_shader_load_from_binary(const char *binary,
+ const int binary_format,
+ const int binary_len,
+ const char *shname)
+{
+ BLI_assert(GL_ARB_get_program_binary);
+ int success;
+ int program = glCreateProgram();
+
+ glProgramBinary(program, binary_format, binary, binary_len);
+ glGetProgramiv(program, GL_LINK_STATUS, &success);
+
+ if (success) {
+ glUseProgram(program);
+
+ GPUShader *shader = (GPUShader *)MEM_callocN(sizeof(*shader), __func__);
+ shader->interface = GPU_shaderinterface_create(program);
+ shader->program = program;
+
+#ifndef NDEBUG
+ BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
+#else
+ UNUSED_VARS(shname);
+#endif
+
+ return shader;
+ }
+
+ glDeleteProgram(program);
+ return NULL;
+}
+
+GPUShader *GPU_shader_create_ex(const char *vertexcode,
+ const char *fragcode,
+ const char *geocode,
+ const char *libcode,
+ const char *defines,
+ const eGPUShaderTFBType tf_type,
+ const char **tf_names,
+ const int tf_count,
+ const char *shname)
+{
+ GLint status;
+ GLchar log[5000];
+ GLsizei length = 0;
+ GPUShader *shader;
+ char standard_defines[MAX_DEFINE_LENGTH] = "";
+ char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
+
+ shader = (GPUShader *)MEM_callocN(sizeof(GPUShader), "GPUShader");
+ gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
+
+#ifndef NDEBUG
+ BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
+#else
+ UNUSED_VARS(shname);
+#endif
+
+ /* At least a vertex shader and a fragment shader are required. */
+ BLI_assert((fragcode != NULL) && (vertexcode != NULL));
+
+ if (vertexcode) {
+ shader->vertex = glCreateShader(GL_VERTEX_SHADER);
+ }
+ if (fragcode) {
+ shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
+ }
+ if (geocode) {
+ shader->geometry = glCreateShader(GL_GEOMETRY_SHADER);
+ }
+
+ shader->program = glCreateProgram();
+
+ if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) ||
+ (geocode && !shader->geometry)) {
+ fprintf(stderr, "GPUShader, object creation failed.\n");
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ gpu_shader_standard_defines(standard_defines);
+ gpu_shader_standard_extensions(standard_extensions);
+
+ if (vertexcode) {
+ const char *source[7];
+ /* custom limit, may be too small, beware */
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] =
+ "#define GPU_VERTEX_SHADER\n"
+ "#define IN_OUT out\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (geocode) {
+ source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ }
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ source[num_source++] = vertexcode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
+
+ glAttachShader(shader->program, shader->vertex);
+ glShaderSource(shader->vertex, num_source, source, NULL);
+
+ glCompileShader(shader->vertex);
+ glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (fragcode) {
+ const char *source[8];
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] =
+ "#define GPU_FRAGMENT_SHADER\n"
+ "#define IN_OUT in\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (geocode) {
+ source[num_source++] = "#define USE_GEOMETRY_SHADER\n";
+ }
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ if (libcode) {
+ source[num_source++] = libcode;
+ }
+ source[num_source++] = fragcode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
+
+ glAttachShader(shader->program, shader->fragment);
+ glShaderSource(shader->fragment, num_source, source, NULL);
+
+ glCompileShader(shader->fragment);
+ glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (geocode) {
+ const char *source[6];
+ int num_source = 0;
+
+ source[num_source++] = gpu_shader_version();
+ source[num_source++] = "#define GPU_GEOMETRY_SHADER\n";
+ source[num_source++] = standard_extensions;
+ source[num_source++] = standard_defines;
+
+ if (defines) {
+ source[num_source++] = defines;
+ }
+ source[num_source++] = geocode;
+
+ gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
+
+ glAttachShader(shader->program, shader->geometry);
+ glShaderSource(shader->geometry, num_source, source, NULL);
+
+ glCompileShader(shader->geometry);
+ glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
+
+ if (!status) {
+ glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
+ shader_print_errors("compile", log, source, num_source);
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+ }
+
+ if (tf_names != NULL) {
+ glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
+ /* Primitive type must be setup */
+ BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
+ shader->feedback_transform_type = tf_type;
+ }
+
+ glLinkProgram(shader->program);
+ glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
+ if (!status) {
+ glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
+ /* print attached shaders in pipeline order */
+ if (defines) {
+ shader_print_errors("linking", log, &defines, 1);
+ }
+ if (vertexcode) {
+ shader_print_errors("linking", log, &vertexcode, 1);
+ }
+ if (geocode) {
+ shader_print_errors("linking", log, &geocode, 1);
+ }
+ if (libcode) {
+ shader_print_errors("linking", log, &libcode, 1);
+ }
+ if (fragcode) {
+ shader_print_errors("linking", log, &fragcode, 1);
+ }
+
+ GPU_shader_free(shader);
+ return NULL;
+ }
+
+ glUseProgram(shader->program);
+ shader->interface = GPU_shaderinterface_create(shader->program);
+
+ return shader;
+}
+
+#undef DEBUG_SHADER_GEOMETRY
+#undef DEBUG_SHADER_FRAGMENT
+#undef DEBUG_SHADER_VERTEX
+#undef DEBUG_SHADER_NONE
+
+void GPU_shader_free(GPUShader *shader)
+{
+#if 0 /* Would be nice to have, but for now the Deferred compilation \
+ * does not have a GPUContext. */
+ BLI_assert(GPU_context_active_get() != NULL);
+#endif
+ BLI_assert(shader);
+
+ if (shader->vertex) {
+ glDeleteShader(shader->vertex);
+ }
+ if (shader->geometry) {
+ glDeleteShader(shader->geometry);
+ }
+ if (shader->fragment) {
+ glDeleteShader(shader->fragment);
+ }
+ if (shader->program) {
+ glDeleteProgram(shader->program);
+ }
+
+ if (shader->interface) {
+ GPU_shaderinterface_discard(shader->interface);
+ }
+
+ MEM_freeN(shader);
+}
+
+static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
+{
+ bool is_alloc = false;
+ if (str_arr == NULL) {
+ *r_is_alloc = false;
+ return NULL;
+ }
+ /* Skip empty strings (avoid alloc if we can). */
+ while (str_arr[0] && str_arr[0][0] == '\0') {
+ str_arr++;
+ }
+ int i;
+ for (i = 0; str_arr[i]; i++) {
+ if (i != 0 && str_arr[i][0] != '\0') {
+ is_alloc = true;
+ }
+ }
+ *r_is_alloc = is_alloc;
+ if (is_alloc) {
+ return BLI_string_join_arrayN(str_arr, i);
+ }
+
+ return str_arr[0];
+}
+
+/**
+ * Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
+ *
+ * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
+ *
+ * It has the advantage that each item can be conditionally included
+ * without having to build the string inline, then free it.
+ *
+ * \param params: NULL terminated arrays of strings.
+ *
+ * Example:
+ * \code{.c}
+ * sh = GPU_shader_create_from_arrays({
+ * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
+ * .geom = (const char *[]){shader_geom_glsl, NULL},
+ * .frag = (const char *[]){shader_frag_glsl, NULL},
+ * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
+ * });
+ * \endcode
+ */
+struct GPUShader *GPU_shader_create_from_arrays_impl(
+ const struct GPU_ShaderCreateFromArray_Params *params)
+{
+ struct {
+ const char *str;
+ bool is_alloc;
+ } str_dst[4] = {{0}};
+ const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs};
+
+ for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
+ str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
+ }
+
+ GPUShader *sh = GPU_shader_create(
+ str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
+
+ for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
+ if (str_dst[i].is_alloc) {
+ MEM_freeN((void *)str_dst[i].str);
+ }
+ }
+ return sh;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Binding
+ * \{ */
+
+void GPU_shader_bind(GPUShader *shader)
+{
+ BLI_assert(shader && shader->program);
+
+ glUseProgram(shader->program);
+ GPU_matrix_bind(shader->interface);
+ GPU_shader_set_srgb_uniform(shader->interface);
+}
+
+void GPU_shader_unbind(void)
+{
+ glUseProgram(0);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Transform feedback
+ * \{ */
+
+bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
+{
+ if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
+ return false;
+ }
+
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
+
+ switch (shader->feedback_transform_type) {
+ case GPU_SHADER_TFB_POINTS:
+ glBeginTransformFeedback(GL_POINTS);
+ return true;
+ case GPU_SHADER_TFB_LINES:
+ glBeginTransformFeedback(GL_LINES);
+ return true;
+ case GPU_SHADER_TFB_TRIANGLES:
+ glBeginTransformFeedback(GL_TRIANGLES);
+ return true;
+ default:
+ return false;
+ }
+}
+
+void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
+{
+ glEndTransformFeedback();
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniforms / Resource location
+ * \{ */
+
+int GPU_shader_get_uniform(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
+ return uniform ? uniform->location : -1;
+}
+
+int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
+{
+ BLI_assert(shader && shader->program);
+ return GPU_shaderinterface_uniform_builtin(shader->interface,
+ static_cast<GPUUniformBuiltin>(builtin));
+}
+
+int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
+{
+ BLI_assert(shader && shader->program);
+ return GPU_shaderinterface_block_builtin(shader->interface,
+ static_cast<GPUUniformBlockBuiltin>(builtin));
+}
+
+int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ return ubo ? ubo->location : -1;
+}
+
+int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
+ return ubo ? ubo->binding : -1;
+}
+
+int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
+ return tex ? tex->binding : -1;
+}
+
+int GPU_shader_get_attribute(GPUShader *shader, const char *name)
+{
+ BLI_assert(shader && shader->program);
+ const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
+ return attr ? attr->location : -1;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Getters
+ * \{ */
+
+/* Clement : Temp */
+int GPU_shader_get_program(GPUShader *shader)
+{
+ return (int)shader->program;
+}
+
+char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len)
+{
+ BLI_assert(GLEW_ARB_get_program_binary);
+ char *r_binary;
+ int binary_len = 0;
+
+ glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len);
+ r_binary = (char *)MEM_mallocN(binary_len, __func__);
+ glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary);
+
+ if (r_binary_len) {
+ *r_binary_len = binary_len;
+ }
+
+ return r_binary;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Uniforms setters
+ * \{ */
+
+void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ glUniform1f(location, value);
+}
+
+void GPU_shader_uniform_vector(
+ GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
+{
+ if (location == -1 || value == NULL) {
+ return;
+ }
+
+ switch (length) {
+ case 1:
+ glUniform1fv(location, arraysize, value);
+ break;
+ case 2:
+ glUniform2fv(location, arraysize, value);
+ break;
+ case 3:
+ glUniform3fv(location, arraysize, value);
+ break;
+ case 4:
+ glUniform4fv(location, arraysize, value);
+ break;
+ case 9:
+ glUniformMatrix3fv(location, arraysize, 0, value);
+ break;
+ case 16:
+ glUniformMatrix4fv(location, arraysize, 0, value);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ glUniform1i(location, value);
+}
+
+void GPU_shader_uniform_vector_int(
+ GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
+{
+ if (location == -1) {
+ return;
+ }
+
+ switch (length) {
+ case 1:
+ glUniform1iv(location, arraysize, value);
+ break;
+ case 2:
+ glUniform2iv(location, arraysize, value);
+ break;
+ case 3:
+ glUniform3iv(location, arraysize, value);
+ break;
+ case 4:
+ glUniform4iv(location, arraysize, value);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name sRGB Rendering Workaround
+ *
+ * The viewport overlay frame-buffer is sRGB and will expect shaders to output display referred
+ * Linear colors. But other frame-buffers (i.e: the area frame-buffers) are not sRGB and require
+ * the shader output color to be in sRGB space
+ * (assumed display encoded color-space as the time of writing).
+ * For this reason we have a uniform to switch the transform on and off depending on the current
+ * frame-buffer color-space.
+ * \{ */
+
+static int g_shader_builtin_srgb_transform = 0;
+
+void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
+{
+ int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
+ if (loc != -1) {
+ glUniform1i(loc, g_shader_builtin_srgb_transform);
+ }
+}
+
+void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear)
+{
+ g_shader_builtin_srgb_transform = use_srgb_to_linear;
+}
+
+/** \} */
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 9ea798e5669..9c0692b76e2 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -153,11 +153,6 @@ const struct GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN] = {
/* cache of built-in shaders (each is created on first use) */
static GPUShader *builtin_shaders[GPU_SHADER_CFG_LEN][GPU_SHADER_BUILTIN_LEN] = {{NULL}};
-static int g_shader_builtin_srgb_transform = 0;
-
-#ifndef NDEBUG
-static uint g_shaderid = 0;
-#endif
typedef struct {
const char *vert;
@@ -168,727 +163,6 @@ typedef struct {
const char *defs;
} GPUShaderStages;
-static void shader_print_errors(const char *task, const char *log, const char **code, int totcode)
-{
- int line = 1;
-
- fprintf(stderr, "GPUShader: %s error:\n", task);
-
- for (int i = 0; i < totcode; i++) {
- const char *c, *pos, *end = code[i] + strlen(code[i]);
-
- if (G.debug & G_DEBUG) {
- fprintf(stderr, "===== shader string %d ====\n", i + 1);
-
- c = code[i];
- while ((c < end) && (pos = strchr(c, '\n'))) {
- fprintf(stderr, "%2d ", line);
- fwrite(c, (pos + 1) - c, 1, stderr);
- c = pos + 1;
- line++;
- }
-
- fprintf(stderr, "%s", c);
- }
- }
-
- fprintf(stderr, "%s\n", log);
-}
-
-static const char *gpu_shader_version(void)
-{
- return "#version 330\n";
-}
-
-static void gpu_shader_standard_extensions(char defines[MAX_EXT_DEFINE_LENGTH])
-{
- /* enable extensions for features that are not part of our base GLSL version
- * don't use an extension for something already available!
- */
-
- if (GLEW_ARB_texture_gather) {
- /* There is a bug on older Nvidia GPU where GL_ARB_texture_gather
- * is reported to be supported but yield a compile error (see T55802). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) || GLEW_VERSION_4_0) {
- strcat(defines, "#extension GL_ARB_texture_gather: enable\n");
-
- /* Some drivers don't agree on GLEW_ARB_texture_gather and the actual support in the
- * shader so double check the preprocessor define (see T56544). */
- if (!GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY) && !GLEW_VERSION_4_0) {
- strcat(defines, "#ifdef GL_ARB_texture_gather\n");
- strcat(defines, "# define GPU_ARB_texture_gather\n");
- strcat(defines, "#endif\n");
- }
- else {
- strcat(defines, "#define GPU_ARB_texture_gather\n");
- }
- }
- }
- if (GLEW_ARB_texture_query_lod) {
- /* a #version 400 feature, but we use #version 330 maximum so use extension */
- strcat(defines, "#extension GL_ARB_texture_query_lod: enable\n");
- }
- if (GLEW_ARB_shader_draw_parameters) {
- strcat(defines, "#extension GL_ARB_shader_draw_parameters : enable\n");
- }
- if (GPU_arb_texture_cube_map_array_is_supported()) {
- strcat(defines, "#extension GL_ARB_texture_cube_map_array : enable\n");
- strcat(defines, "#define GPU_ARB_texture_cube_map_array\n");
- }
-}
-
-static void gpu_shader_standard_defines(char defines[MAX_DEFINE_LENGTH])
-{
- /* some useful defines to detect GPU type */
- if (GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_ATI\n");
- if (GPU_crappy_amd_driver()) {
- strcat(defines, "#define GPU_DEPRECATED_AMD_DRIVER\n");
- }
- }
- else if (GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_NVIDIA\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- strcat(defines, "#define GPU_INTEL\n");
- }
-
- /* some useful defines to detect OS type */
- if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_WIN, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_WIN\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_MAC\n");
- }
- else if (GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_ANY)) {
- strcat(defines, "#define OS_UNIX\n");
- }
-
- float derivatives_factors[2];
- GPU_get_dfdy_factors(derivatives_factors);
- if (derivatives_factors[0] == 1.0f) {
- strcat(defines, "#define DFDX_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDX_SIGN -1.0\n");
- }
-
- if (derivatives_factors[1] == 1.0f) {
- strcat(defines, "#define DFDY_SIGN 1.0\n");
- }
- else {
- strcat(defines, "#define DFDY_SIGN -1.0\n");
- }
-}
-
-GPUShader *GPU_shader_create(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- const char *shname)
-{
- return GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, shname);
-}
-
-GPUShader *GPU_shader_create_from_python(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines)
-{
- char *libcodecat = NULL;
-
- if (libcode == NULL) {
- libcode = datatoc_gpu_shader_colorspace_lib_glsl;
- }
- else {
- libcode = libcodecat = BLI_strdupcat(libcode, datatoc_gpu_shader_colorspace_lib_glsl);
- }
-
- GPUShader *sh = GPU_shader_create_ex(
- vertexcode, fragcode, geocode, libcode, defines, GPU_SHADER_TFB_NONE, NULL, 0, NULL);
-
- MEM_SAFE_FREE(libcodecat);
- return sh;
-}
-
-GPUShader *GPU_shader_load_from_binary(const char *binary,
- const int binary_format,
- const int binary_len,
- const char *shname)
-{
- BLI_assert(GL_ARB_get_program_binary);
- int success;
- int program = glCreateProgram();
-
- glProgramBinary(program, binary_format, binary, binary_len);
- glGetProgramiv(program, GL_LINK_STATUS, &success);
-
- if (success) {
- glUseProgram(program);
-
- GPUShader *shader = MEM_callocN(sizeof(*shader), __func__);
- shader->interface = GPU_shaderinterface_create(program);
- shader->program = program;
-
-#ifndef NDEBUG
- BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
-#else
- UNUSED_VARS(shname);
-#endif
-
- return shader;
- }
-
- glDeleteProgram(program);
- return NULL;
-}
-
-#define DEBUG_SHADER_NONE ""
-#define DEBUG_SHADER_VERTEX "vert"
-#define DEBUG_SHADER_FRAGMENT "frag"
-#define DEBUG_SHADER_GEOMETRY "geom"
-
-/**
- * Dump GLSL shaders to disk
- *
- * This is used for profiling shader performance externally and debug if shader code is correct.
- * If called with no code, it simply bumps the shader index, so different shaders for the same
- * program share the same index.
- */
-static void gpu_dump_shaders(const char **code, const int num_shaders, const char *extension)
-{
- if ((G.debug & G_DEBUG_GPU_SHADERS) == 0) {
- return;
- }
-
- /* We use the same shader index for shaders in the same program.
- * So we call this function once before calling for the individual shaders. */
- static int shader_index = 0;
- if (code == NULL) {
- shader_index++;
- BLI_assert(STREQ(DEBUG_SHADER_NONE, extension));
- return;
- }
-
- /* Determine the full path of the new shader. */
- char shader_path[FILE_MAX];
-
- char file_name[512] = {'\0'};
- sprintf(file_name, "%04d.%s", shader_index, extension);
-
- BLI_join_dirfile(shader_path, sizeof(shader_path), BKE_tempdir_session(), file_name);
-
- /* Write shader to disk. */
- FILE *f = fopen(shader_path, "w");
- if (f == NULL) {
- printf("Error writing to file: %s\n", shader_path);
- }
- for (int j = 0; j < num_shaders; j++) {
- fprintf(f, "%s", code[j]);
- }
- fclose(f);
- printf("Shader file written to disk: %s\n", shader_path);
-}
-
-GPUShader *GPU_shader_create_ex(const char *vertexcode,
- const char *fragcode,
- const char *geocode,
- const char *libcode,
- const char *defines,
- const eGPUShaderTFBType tf_type,
- const char **tf_names,
- const int tf_count,
- const char *shname)
-{
- GLint status;
- GLchar log[5000];
- GLsizei length = 0;
- GPUShader *shader;
- char standard_defines[MAX_DEFINE_LENGTH] = "";
- char standard_extensions[MAX_EXT_DEFINE_LENGTH] = "";
-
- shader = MEM_callocN(sizeof(GPUShader), "GPUShader");
- gpu_dump_shaders(NULL, 0, DEBUG_SHADER_NONE);
-
-#ifndef NDEBUG
- BLI_snprintf(shader->name, sizeof(shader->name), "%s_%u", shname, g_shaderid++);
-#else
- UNUSED_VARS(shname);
-#endif
-
- /* At least a vertex shader and a fragment shader are required. */
- BLI_assert((fragcode != NULL) && (vertexcode != NULL));
-
- if (vertexcode) {
- shader->vertex = glCreateShader(GL_VERTEX_SHADER);
- }
- if (fragcode) {
- shader->fragment = glCreateShader(GL_FRAGMENT_SHADER);
- }
- if (geocode) {
- shader->geometry = glCreateShader(GL_GEOMETRY_SHADER);
- }
-
- shader->program = glCreateProgram();
-
- if (!shader->program || (vertexcode && !shader->vertex) || (fragcode && !shader->fragment) ||
- (geocode && !shader->geometry)) {
- fprintf(stderr, "GPUShader, object creation failed.\n");
- GPU_shader_free(shader);
- return NULL;
- }
-
- gpu_shader_standard_defines(standard_defines);
- gpu_shader_standard_extensions(standard_extensions);
-
- if (vertexcode) {
- const char *source[6];
- /* custom limit, may be too small, beware */
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] =
- "#define GPU_VERTEX_SHADER\n"
- "#define IN_OUT out\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- source[num_source++] = vertexcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_VERTEX);
-
- glAttachShader(shader->program, shader->vertex);
- glShaderSource(shader->vertex, num_source, source, NULL);
-
- glCompileShader(shader->vertex);
- glGetShaderiv(shader->vertex, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->vertex, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (fragcode) {
- const char *source[7];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] =
- "#define GPU_FRAGMENT_SHADER\n"
- "#define IN_OUT in\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- if (libcode) {
- source[num_source++] = libcode;
- }
- source[num_source++] = fragcode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_FRAGMENT);
-
- glAttachShader(shader->program, shader->fragment);
- glShaderSource(shader->fragment, num_source, source, NULL);
-
- glCompileShader(shader->fragment);
- glGetShaderiv(shader->fragment, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->fragment, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (geocode) {
- const char *source[6];
- int num_source = 0;
-
- source[num_source++] = gpu_shader_version();
- source[num_source++] = "#define GPU_GEOMETRY_SHADER\n";
- source[num_source++] = standard_extensions;
- source[num_source++] = standard_defines;
-
- if (defines) {
- source[num_source++] = defines;
- }
- source[num_source++] = geocode;
-
- gpu_dump_shaders(source, num_source, DEBUG_SHADER_GEOMETRY);
-
- glAttachShader(shader->program, shader->geometry);
- glShaderSource(shader->geometry, num_source, source, NULL);
-
- glCompileShader(shader->geometry);
- glGetShaderiv(shader->geometry, GL_COMPILE_STATUS, &status);
-
- if (!status) {
- glGetShaderInfoLog(shader->geometry, sizeof(log), &length, log);
- shader_print_errors("compile", log, source, num_source);
-
- GPU_shader_free(shader);
- return NULL;
- }
- }
-
- if (tf_names != NULL) {
- glTransformFeedbackVaryings(shader->program, tf_count, tf_names, GL_INTERLEAVED_ATTRIBS);
- /* Primitive type must be setup */
- BLI_assert(tf_type != GPU_SHADER_TFB_NONE);
- shader->feedback_transform_type = tf_type;
- }
-
- glLinkProgram(shader->program);
- glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
- if (!status) {
- glGetProgramInfoLog(shader->program, sizeof(log), &length, log);
- /* print attached shaders in pipeline order */
- if (vertexcode) {
- shader_print_errors("linking", log, &vertexcode, 1);
- }
- if (geocode) {
- shader_print_errors("linking", log, &geocode, 1);
- }
- if (libcode) {
- shader_print_errors("linking", log, &libcode, 1);
- }
- if (fragcode) {
- shader_print_errors("linking", log, &fragcode, 1);
- }
-
- GPU_shader_free(shader);
- return NULL;
- }
-
- glUseProgram(shader->program);
- shader->interface = GPU_shaderinterface_create(shader->program);
-
- return shader;
-}
-
-#undef DEBUG_SHADER_GEOMETRY
-#undef DEBUG_SHADER_FRAGMENT
-#undef DEBUG_SHADER_VERTEX
-#undef DEBUG_SHADER_NONE
-
-static const char *string_join_array_maybe_alloc(const char **str_arr, bool *r_is_alloc)
-{
- bool is_alloc = false;
- if (str_arr == NULL) {
- *r_is_alloc = false;
- return NULL;
- }
- /* Skip empty strings (avoid alloc if we can). */
- while (str_arr[0] && str_arr[0][0] == '\0') {
- str_arr++;
- }
- int i;
- for (i = 0; str_arr[i]; i++) {
- if (i != 0 && str_arr[i][0] != '\0') {
- is_alloc = true;
- }
- }
- *r_is_alloc = is_alloc;
- if (is_alloc) {
- return BLI_string_join_arrayN(str_arr, i);
- }
- else {
- return str_arr[0];
- }
-}
-
-/**
- * Use via #GPU_shader_create_from_arrays macro (avoids passing in param).
- *
- * Similar to #DRW_shader_create_with_lib with the ability to include libs for each type of shader.
- *
- * It has the advantage that each item can be conditionally included
- * without having to build the string inline, then free it.
- *
- * \param params: NULL terminated arrays of strings.
- *
- * Example:
- * \code{.c}
- * sh = GPU_shader_create_from_arrays({
- * .vert = (const char *[]){shader_lib_glsl, shader_vert_glsl, NULL},
- * .geom = (const char *[]){shader_geom_glsl, NULL},
- * .frag = (const char *[]){shader_frag_glsl, NULL},
- * .defs = (const char *[]){"#define DEFINE\n", test ? "#define OTHER_DEFINE\n" : "", NULL},
- * });
- * \endcode
- */
-struct GPUShader *GPU_shader_create_from_arrays_impl(
- const struct GPU_ShaderCreateFromArray_Params *params)
-{
- struct {
- const char *str;
- bool is_alloc;
- } str_dst[4] = {{0}};
- const char **str_src[4] = {params->vert, params->frag, params->geom, params->defs};
-
- for (int i = 0; i < ARRAY_SIZE(str_src); i++) {
- str_dst[i].str = string_join_array_maybe_alloc(str_src[i], &str_dst[i].is_alloc);
- }
-
- GPUShader *sh = GPU_shader_create(
- str_dst[0].str, str_dst[1].str, str_dst[2].str, NULL, str_dst[3].str, __func__);
-
- for (int i = 0; i < ARRAY_SIZE(str_dst); i++) {
- if (str_dst[i].is_alloc) {
- MEM_freeN((void *)str_dst[i].str);
- }
- }
- return sh;
-}
-
-void GPU_shader_bind(GPUShader *shader)
-{
- BLI_assert(shader && shader->program);
-
- glUseProgram(shader->program);
- GPU_matrix_bind(shader->interface);
- GPU_shader_set_srgb_uniform(shader->interface);
-}
-
-void GPU_shader_unbind(void)
-{
- glUseProgram(0);
-}
-
-bool GPU_shader_transform_feedback_enable(GPUShader *shader, uint vbo_id)
-{
- if (shader->feedback_transform_type == GPU_SHADER_TFB_NONE) {
- return false;
- }
-
- glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, vbo_id);
-
- switch (shader->feedback_transform_type) {
- case GPU_SHADER_TFB_POINTS:
- glBeginTransformFeedback(GL_POINTS);
- return true;
- case GPU_SHADER_TFB_LINES:
- glBeginTransformFeedback(GL_LINES);
- return true;
- case GPU_SHADER_TFB_TRIANGLES:
- glBeginTransformFeedback(GL_TRIANGLES);
- return true;
- default:
- return false;
- }
-}
-
-void GPU_shader_transform_feedback_disable(GPUShader *UNUSED(shader))
-{
- glEndTransformFeedback();
-}
-
-void GPU_shader_free(GPUShader *shader)
-{
-#if 0 /* Would be nice to have, but for now the Deferred compilation \
- * does not have a GPUContext. */
- BLI_assert(GPU_context_active_get() != NULL);
-#endif
- BLI_assert(shader);
-
- if (shader->vertex) {
- glDeleteShader(shader->vertex);
- }
- if (shader->geometry) {
- glDeleteShader(shader->geometry);
- }
- if (shader->fragment) {
- glDeleteShader(shader->fragment);
- }
- if (shader->program) {
- glDeleteProgram(shader->program);
- }
-
- if (shader->interface) {
- GPU_shaderinterface_discard(shader->interface);
- }
-
- MEM_freeN(shader);
-}
-
-int GPU_shader_get_uniform(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *uniform = GPU_shaderinterface_uniform(shader->interface, name);
- return uniform ? uniform->location : -1;
-}
-
-int GPU_shader_get_builtin_uniform(GPUShader *shader, int builtin)
-{
- BLI_assert(shader && shader->program);
- return GPU_shaderinterface_uniform_builtin(shader->interface, builtin);
-}
-
-int GPU_shader_get_builtin_block(GPUShader *shader, int builtin)
-{
- BLI_assert(shader && shader->program);
- return GPU_shaderinterface_block_builtin(shader->interface, builtin);
-}
-
-int GPU_shader_get_uniform_block(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
- return ubo ? ubo->location : -1;
-}
-
-int GPU_shader_get_uniform_block_binding(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *ubo = GPU_shaderinterface_ubo(shader->interface, name);
- return ubo ? ubo->binding : -1;
-}
-
-int GPU_shader_get_texture_binding(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *tex = GPU_shaderinterface_uniform(shader->interface, name);
- return tex ? tex->binding : -1;
-}
-
-void *GPU_shader_get_interface(GPUShader *shader)
-{
- return shader->interface;
-}
-
-/* Clement : Temp */
-int GPU_shader_get_program(GPUShader *shader)
-{
- return (int)shader->program;
-}
-
-void GPU_shader_uniform_float(GPUShader *UNUSED(shader), int location, float value)
-{
- if (location == -1) {
- return;
- }
-
- glUniform1f(location, value);
-}
-
-void GPU_shader_uniform_vector(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const float *value)
-{
- if (location == -1 || value == NULL) {
- return;
- }
-
- switch (length) {
- case 1:
- glUniform1fv(location, arraysize, value);
- break;
- case 2:
- glUniform2fv(location, arraysize, value);
- break;
- case 3:
- glUniform3fv(location, arraysize, value);
- break;
- case 4:
- glUniform4fv(location, arraysize, value);
- break;
- case 9:
- glUniformMatrix3fv(location, arraysize, 0, value);
- break;
- case 16:
- glUniformMatrix4fv(location, arraysize, 0, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
-}
-
-void GPU_shader_uniform_vector_int(
- GPUShader *UNUSED(shader), int location, int length, int arraysize, const int *value)
-{
- if (location == -1) {
- return;
- }
-
- switch (length) {
- case 1:
- glUniform1iv(location, arraysize, value);
- break;
- case 2:
- glUniform2iv(location, arraysize, value);
- break;
- case 3:
- glUniform3iv(location, arraysize, value);
- break;
- case 4:
- glUniform4iv(location, arraysize, value);
- break;
- default:
- BLI_assert(0);
- break;
- }
-}
-
-void GPU_shader_uniform_int(GPUShader *UNUSED(shader), int location, int value)
-{
- if (location == -1) {
- return;
- }
-
- glUniform1i(location, value);
-}
-
-void GPU_shader_set_srgb_uniform(const GPUShaderInterface *interface)
-{
- int32_t loc = GPU_shaderinterface_uniform_builtin(interface, GPU_UNIFORM_SRGB_TRANSFORM);
- if (loc != -1) {
- glUniform1i(loc, g_shader_builtin_srgb_transform);
- }
-}
-
-int GPU_shader_get_attribute(GPUShader *shader, const char *name)
-{
- BLI_assert(shader && shader->program);
- const GPUShaderInput *attr = GPU_shaderinterface_attr(shader->interface, name);
- return attr ? attr->location : -1;
-}
-
-char *GPU_shader_get_binary(GPUShader *shader, uint *r_binary_format, int *r_binary_len)
-{
- BLI_assert(GLEW_ARB_get_program_binary);
- char *r_binary;
- int binary_len = 0;
-
- glGetProgramiv(shader->program, GL_PROGRAM_BINARY_LENGTH, &binary_len);
- r_binary = MEM_mallocN(binary_len, __func__);
- glGetProgramBinary(shader->program, binary_len, NULL, r_binary_format, r_binary);
-
- if (r_binary_len) {
- *r_binary_len = binary_len;
- }
-
- return r_binary;
-}
-
-void GPU_shader_set_framebuffer_srgb_target(int use_srgb_to_linear)
-{
- g_shader_builtin_srgb_transform = use_srgb_to_linear;
-}
-
static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
[GPU_SHADER_TEXT] =
{
@@ -1242,6 +516,7 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader,
return *sh_p;
}
+
GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
{
return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT);
diff --git a/source/blender/gpu/intern/gpu_shader_interface.c b/source/blender/gpu/intern/gpu_shader_interface.cc
index 9d9f98c6bb0..7ac4365dd91 100644
--- a/source/blender/gpu/intern/gpu_shader_interface.c
+++ b/source/blender/gpu/intern/gpu_shader_interface.cc
@@ -47,47 +47,66 @@
static const char *BuiltinUniform_name(GPUUniformBuiltin u)
{
- static const char *names[] = {
- [GPU_UNIFORM_MODEL] = "ModelMatrix",
- [GPU_UNIFORM_VIEW] = "ViewMatrix",
- [GPU_UNIFORM_MODELVIEW] = "ModelViewMatrix",
- [GPU_UNIFORM_PROJECTION] = "ProjectionMatrix",
- [GPU_UNIFORM_VIEWPROJECTION] = "ViewProjectionMatrix",
- [GPU_UNIFORM_MVP] = "ModelViewProjectionMatrix",
-
- [GPU_UNIFORM_MODEL_INV] = "ModelMatrixInverse",
- [GPU_UNIFORM_VIEW_INV] = "ViewMatrixInverse",
- [GPU_UNIFORM_MODELVIEW_INV] = "ModelViewMatrixInverse",
- [GPU_UNIFORM_PROJECTION_INV] = "ProjectionMatrixInverse",
- [GPU_UNIFORM_VIEWPROJECTION_INV] = "ViewProjectionMatrixInverse",
-
- [GPU_UNIFORM_NORMAL] = "NormalMatrix",
- [GPU_UNIFORM_ORCO] = "OrcoTexCoFactors",
- [GPU_UNIFORM_CLIPPLANES] = "WorldClipPlanes",
-
- [GPU_UNIFORM_COLOR] = "color",
- [GPU_UNIFORM_BASE_INSTANCE] = "baseInstance",
- [GPU_UNIFORM_RESOURCE_CHUNK] = "resourceChunk",
- [GPU_UNIFORM_RESOURCE_ID] = "resourceId",
- [GPU_UNIFORM_SRGB_TRANSFORM] = "srgbTarget",
-
- [GPU_NUM_UNIFORMS] = NULL,
- };
-
- return names[u];
+ switch (u) {
+ case GPU_UNIFORM_MODEL:
+ return "ModelMatrix";
+ case GPU_UNIFORM_VIEW:
+ return "ViewMatrix";
+ case GPU_UNIFORM_MODELVIEW:
+ return "ModelViewMatrix";
+ case GPU_UNIFORM_PROJECTION:
+ return "ProjectionMatrix";
+ case GPU_UNIFORM_VIEWPROJECTION:
+ return "ViewProjectionMatrix";
+ case GPU_UNIFORM_MVP:
+ return "ModelViewProjectionMatrix";
+
+ case GPU_UNIFORM_MODEL_INV:
+ return "ModelMatrixInverse";
+ case GPU_UNIFORM_VIEW_INV:
+ return "ViewMatrixInverse";
+ case GPU_UNIFORM_MODELVIEW_INV:
+ return "ModelViewMatrixInverse";
+ case GPU_UNIFORM_PROJECTION_INV:
+ return "ProjectionMatrixInverse";
+ case GPU_UNIFORM_VIEWPROJECTION_INV:
+ return "ViewProjectionMatrixInverse";
+
+ case GPU_UNIFORM_NORMAL:
+ return "NormalMatrix";
+ case GPU_UNIFORM_ORCO:
+ return "OrcoTexCoFactors";
+ case GPU_UNIFORM_CLIPPLANES:
+ return "WorldClipPlanes";
+
+ case GPU_UNIFORM_COLOR:
+ return "color";
+ case GPU_UNIFORM_BASE_INSTANCE:
+ return "baseInstance";
+ case GPU_UNIFORM_RESOURCE_CHUNK:
+ return "resourceChunk";
+ case GPU_UNIFORM_RESOURCE_ID:
+ return "resourceId";
+ case GPU_UNIFORM_SRGB_TRANSFORM:
+ return "srgbTarget";
+
+ default:
+ return NULL;
+ }
}
static const char *BuiltinUniformBlock_name(GPUUniformBlockBuiltin u)
{
- static const char *names[] = {
- [GPU_UNIFORM_BLOCK_VIEW] = "viewBlock",
- [GPU_UNIFORM_BLOCK_MODEL] = "modelBlock",
- [GPU_UNIFORM_BLOCK_INFO] = "infoBlock",
-
- [GPU_NUM_UNIFORM_BLOCKS] = NULL,
- };
-
- return names[u];
+ switch (u) {
+ case GPU_UNIFORM_BLOCK_VIEW:
+ return "viewBlock";
+ case GPU_UNIFORM_BLOCK_MODEL:
+ return "modelBlock";
+ case GPU_UNIFORM_BLOCK_INFO:
+ return "infoBlock";
+ default:
+ return NULL;
+ }
}
GPU_INLINE bool match(const char *a, const char *b)
@@ -138,13 +157,12 @@ GPU_INLINE const GPUShaderInput *input_lookup(const GPUShaderInterface *shaderfa
}
return NULL; /* not found */
}
- else {
- /* This is a bit dangerous since we could have a hash collision.
- * where the asked uniform that does not exist has the same hash
- * as a real uniform. */
- BLI_assert(match(name, shaderface->name_buffer + inputs[i].name_offset));
- return inputs + i;
- }
+
+ /* This is a bit dangerous since we could have a hash collision.
+ * where the asked uniform that does not exist has the same hash
+ * as a real uniform. */
+ BLI_assert(match(name, shaderface->name_buffer + inputs[i].name_offset));
+ return inputs + i;
}
}
return NULL; /* not found */
@@ -273,7 +291,7 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
/* Bit set to true if uniform comes from a uniform block. */
BLI_bitmap *uniforms_from_blocks = BLI_BITMAP_NEW(active_uniform_len, __func__);
/* Set uniforms from block for exclusion. */
- GLint *ubo_uni_ids = MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
+ GLint *ubo_uni_ids = (GLint *)MEM_mallocN(sizeof(GLint) * max_ubo_uni_len, __func__);
for (int i = 0; i < ubo_len; i++) {
GLint ubo_uni_len;
glGetActiveUniformBlockiv(program, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &ubo_uni_len);
@@ -291,16 +309,18 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
int input_tot_len = attr_len + ubo_len + uniform_len;
size_t interface_size = sizeof(GPUShaderInterface) + sizeof(GPUShaderInput) * input_tot_len;
- GPUShaderInterface *shaderface = MEM_callocN(interface_size, "GPUShaderInterface");
+ GPUShaderInterface *shaderface = (GPUShaderInterface *)MEM_callocN(interface_size,
+ "GPUShaderInterface");
shaderface->attribute_len = attr_len;
shaderface->ubo_len = ubo_len;
shaderface->uniform_len = uniform_len;
- shaderface->name_buffer = MEM_mallocN(name_buffer_len, "name_buffer");
+ shaderface->name_buffer = (char *)MEM_mallocN(name_buffer_len, "name_buffer");
GPUShaderInput *inputs = shaderface->inputs;
/* Temp buffer. */
int input_tmp_len = max_iii(attr_len, ubo_len, uniform_len);
- GPUShaderInput *inputs_tmp = MEM_mallocN(sizeof(GPUShaderInput) * input_tmp_len, "name_buffer");
+ GPUShaderInput *inputs_tmp = (GPUShaderInput *)MEM_mallocN(
+ sizeof(GPUShaderInput) * input_tmp_len, "name_buffer");
/* Attributes */
shaderface->enabled_attr_mask = 0;
@@ -366,27 +386,29 @@ GPUShaderInterface *GPU_shaderinterface_create(int32_t program)
sort_input_list(inputs, inputs_tmp, shaderface->uniform_len);
/* Builtin Uniforms */
- for (GPUUniformBuiltin u = 0; u < GPU_NUM_UNIFORMS; u++) {
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORMS; u_int++) {
+ GPUUniformBuiltin u = static_cast<GPUUniformBuiltin>(u_int);
shaderface->builtins[u] = glGetUniformLocation(program, BuiltinUniform_name(u));
}
/* Builtin Uniforms Blocks */
- for (GPUUniformBlockBuiltin u = 0; u < GPU_NUM_UNIFORM_BLOCKS; u++) {
+ for (int32_t u_int = 0; u_int < GPU_NUM_UNIFORM_BLOCKS; u_int++) {
+ GPUUniformBlockBuiltin u = static_cast<GPUUniformBlockBuiltin>(u_int);
const GPUShaderInput *block = GPU_shaderinterface_ubo(shaderface, BuiltinUniformBlock_name(u));
shaderface->builtin_blocks[u] = (block != NULL) ? block->binding : -1;
}
/* Batches ref buffer */
shaderface->batches_len = GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *),
- "GPUShaderInterface batches");
+ shaderface->batches = (GPUBatch **)MEM_callocN(shaderface->batches_len * sizeof(GPUBatch *),
+ "GPUShaderInterface batches");
MEM_freeN(uniforms_from_blocks);
MEM_freeN(inputs_tmp);
/* Resize name buffer to save some memory. */
if (name_buffer_offset < name_buffer_len) {
- shaderface->name_buffer = MEM_reallocN(shaderface->name_buffer, name_buffer_offset);
+ shaderface->name_buffer = (char *)MEM_reallocN(shaderface->name_buffer, name_buffer_offset);
}
#if DEBUG_SHADER_INTERFACE
@@ -501,8 +523,8 @@ void GPU_shaderinterface_add_batch_ref(GPUShaderInterface *shaderface, GPUBatch
/* Not enough place, realloc the array. */
i = shaderface->batches_len;
shaderface->batches_len += GPU_SHADERINTERFACE_REF_ALLOC_COUNT;
- shaderface->batches = MEM_recallocN(shaderface->batches,
- sizeof(GPUBatch *) * shaderface->batches_len);
+ shaderface->batches = (GPUBatch **)MEM_recallocN(shaderface->batches,
+ sizeof(GPUBatch *) * shaderface->batches_len);
}
shaderface->batches[i] = batch;
}
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
index e04d8655421..0f89fbda737 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -20,9 +20,12 @@
#pragma once
-#include "GPU_glew.h"
#include "GPU_shader_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
struct GPUShader {
/** Handle for full program (links shader stages below). */
GLuint program;
@@ -44,4 +47,8 @@ struct GPUShader {
};
/* XXX do not use it. Special hack to use OCIO with batch API. */
-void immGetProgram(GLuint *program, GPUShaderInterface **shaderface);
+GPUShader *immGetShader(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_state.c b/source/blender/gpu/intern/gpu_state.cc
index bd7aff9772b..794c7a3eb97 100644
--- a/source/blender/gpu/intern/gpu_state.c
+++ b/source/blender/gpu/intern/gpu_state.cc
@@ -268,6 +268,12 @@ void GPU_clip_distances(int distances_new)
distances_enabled = distances_new;
}
+bool GPU_mipmap_enabled(void)
+{
+ /* TODO(fclem) this used to be a userdef option. */
+ return true;
+}
+
/** \name GPU Push/Pop State
* \{ */
@@ -276,33 +282,18 @@ void GPU_clip_distances(int distances_new)
typedef struct {
eGPUAttrMask mask;
- /* GL_ENABLE_BIT */
+ /* GL_BLEND_BIT */
uint is_blend : 1;
- uint is_cull_face : 1;
- uint is_depth_test : 1;
- /* uint is_lighting : 1; */ /* UNUSED */
- uint is_line_smooth : 1;
- uint is_color_logic_op : 1;
- uint is_multisample : 1;
- uint is_polygon_offset_line : 1;
- uint is_polygon_offset_fill : 1;
- uint is_polygon_smooth : 1;
- uint is_sample_alpha_to_coverage : 1;
- uint is_scissor_test : 1;
- uint is_stencil_test : 1;
- uint is_framebuffer_srgb : 1;
-
- bool is_clip_plane[6];
/* GL_DEPTH_BUFFER_BIT */
- /* uint is_depth_test : 1; */
+ uint is_depth_test : 1;
int depth_func;
double depth_clear_value;
bool depth_write_mask;
/* GL_SCISSOR_BIT */
int scissor_box[4];
- /* uint is_scissor_test : 1; */
+ uint is_scissor_test : 1;
/* GL_VIEWPORT_BIT */
int viewport[4];
@@ -315,7 +306,8 @@ typedef struct {
} GPUAttrStack;
static GPUAttrStack state = {
- .top = 0,
+ {},
+ 0,
};
#define AttrStack state
@@ -338,26 +330,6 @@ void gpuPushAttr(eGPUAttrMask mask)
glGetBooleanv(GL_DEPTH_WRITEMASK, (GLboolean *)&Attr.depth_write_mask);
}
- if ((mask & GPU_ENABLE_BIT) != 0) {
- Attr.is_blend = glIsEnabled(GL_BLEND);
-
- for (int i = 0; i < 6; i++) {
- Attr.is_clip_plane[i] = glIsEnabled(GL_CLIP_PLANE0 + i);
- }
-
- Attr.is_cull_face = glIsEnabled(GL_CULL_FACE);
- Attr.is_depth_test = glIsEnabled(GL_DEPTH_TEST);
- Attr.is_line_smooth = glIsEnabled(GL_LINE_SMOOTH);
- Attr.is_color_logic_op = glIsEnabled(GL_COLOR_LOGIC_OP);
- Attr.is_multisample = glIsEnabled(GL_MULTISAMPLE);
- Attr.is_polygon_offset_line = glIsEnabled(GL_POLYGON_OFFSET_LINE);
- Attr.is_polygon_offset_fill = glIsEnabled(GL_POLYGON_OFFSET_FILL);
- Attr.is_polygon_smooth = glIsEnabled(GL_POLYGON_SMOOTH);
- Attr.is_sample_alpha_to_coverage = glIsEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE);
- Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
- Attr.is_stencil_test = glIsEnabled(GL_STENCIL_TEST);
- }
-
if ((mask & GPU_SCISSOR_BIT) != 0) {
Attr.is_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
glGetIntegerv(GL_SCISSOR_BOX, (GLint *)&Attr.scissor_box);
@@ -366,7 +338,6 @@ void gpuPushAttr(eGPUAttrMask mask)
if ((mask & GPU_VIEWPORT_BIT) != 0) {
glGetDoublev(GL_DEPTH_RANGE, (GLdouble *)&Attr.near_far);
glGetIntegerv(GL_VIEWPORT, (GLint *)&Attr.viewport);
- Attr.is_framebuffer_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB);
}
if ((mask & GPU_BLEND_BIT) != 0) {
@@ -401,30 +372,9 @@ void gpuPopAttr(void)
glDepthMask(Attr.depth_write_mask);
}
- if ((mask & GPU_ENABLE_BIT) != 0) {
- restore_mask(GL_BLEND, Attr.is_blend);
-
- for (int i = 0; i < 6; i++) {
- restore_mask(GL_CLIP_PLANE0 + i, Attr.is_clip_plane[i]);
- }
-
- restore_mask(GL_CULL_FACE, Attr.is_cull_face);
- restore_mask(GL_DEPTH_TEST, Attr.is_depth_test);
- restore_mask(GL_LINE_SMOOTH, Attr.is_line_smooth);
- restore_mask(GL_COLOR_LOGIC_OP, Attr.is_color_logic_op);
- restore_mask(GL_MULTISAMPLE, Attr.is_multisample);
- restore_mask(GL_POLYGON_OFFSET_LINE, Attr.is_polygon_offset_line);
- restore_mask(GL_POLYGON_OFFSET_FILL, Attr.is_polygon_offset_fill);
- restore_mask(GL_POLYGON_SMOOTH, Attr.is_polygon_smooth);
- restore_mask(GL_SAMPLE_ALPHA_TO_COVERAGE, Attr.is_sample_alpha_to_coverage);
- restore_mask(GL_SCISSOR_TEST, Attr.is_scissor_test);
- restore_mask(GL_STENCIL_TEST, Attr.is_stencil_test);
- }
-
if ((mask & GPU_VIEWPORT_BIT) != 0) {
glViewport(Attr.viewport[0], Attr.viewport[1], Attr.viewport[2], Attr.viewport[3]);
glDepthRange(Attr.near_far[0], Attr.near_far[1]);
- restore_mask(GL_FRAMEBUFFER_SRGB, Attr.is_framebuffer_srgb);
}
if ((mask & GPU_SCISSOR_BIT) != 0) {
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.cc
index 1e81f6e86a4..5d86f3d16a3 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.cc
@@ -26,6 +26,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_image_types.h"
+#include "DNA_userdef_types.h"
#include "BLI_blenlib.h"
#include "BLI_math_base.h"
@@ -36,7 +37,6 @@
#include "GPU_batch.h"
#include "GPU_context.h"
#include "GPU_debug.h"
-#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_framebuffer.h"
#include "GPU_glew.h"
@@ -45,6 +45,16 @@
#include "gpu_context_private.h"
+#define WARN_NOT_BOUND(_tex) \
+ { \
+ if (_tex->number == -1) { \
+ fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \
+ BLI_assert(0); \
+ return; \
+ } \
+ } \
+ ((void)0)
+
static struct GPUTextureGlobal {
/** Texture used in place of invalid textures (not loaded correctly, missing). */
GPUTexture *invalid_tex_1D;
@@ -71,6 +81,8 @@ typedef enum eGPUTextureFormatFlag {
GPU_FORMAT_ARRAY = (1 << 14),
} eGPUTextureFormatFlag;
+ENUM_OPERATORS(eGPUTextureFormatFlag)
+
/* GPUTexture */
struct GPUTexture {
int w, h, d; /* width/height/depth */
@@ -103,7 +115,7 @@ static void gpu_texture_framebuffer_ensure(GPUTexture *tex);
/* ------ Memory Management ------- */
/* Records every texture allocation / free
* to estimate the Texture Pool Memory consumption */
-static uint memory_usage;
+static uint memory_usage = 0;
static uint gpu_texture_memory_footprint_compute(GPUTexture *tex)
{
@@ -161,54 +173,58 @@ uint GPU_texture_memory_usage_get(void)
static const char *gl_enum_to_str(GLenum e)
{
-#define ENUM_TO_STRING(e) [GL_##e] = STRINGIFY_ARG(e)
- static const char *enum_strings[] = {
- ENUM_TO_STRING(TEXTURE_CUBE_MAP),
- ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY),
- ENUM_TO_STRING(TEXTURE_2D),
- ENUM_TO_STRING(TEXTURE_2D_ARRAY),
- ENUM_TO_STRING(TEXTURE_1D),
- ENUM_TO_STRING(TEXTURE_1D_ARRAY),
- ENUM_TO_STRING(TEXTURE_3D),
- ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE),
- ENUM_TO_STRING(RGBA32F),
- ENUM_TO_STRING(RGBA16F),
- ENUM_TO_STRING(RGBA16UI),
- ENUM_TO_STRING(RGBA16I),
- ENUM_TO_STRING(RGBA16),
- ENUM_TO_STRING(RGBA8UI),
- ENUM_TO_STRING(RGBA8I),
- ENUM_TO_STRING(RGBA8),
- ENUM_TO_STRING(RGB16F),
- ENUM_TO_STRING(RG32F),
- ENUM_TO_STRING(RG16F),
- ENUM_TO_STRING(RG16UI),
- ENUM_TO_STRING(RG16I),
- ENUM_TO_STRING(RG16),
- ENUM_TO_STRING(RG8UI),
- ENUM_TO_STRING(RG8I),
- ENUM_TO_STRING(RG8),
- ENUM_TO_STRING(R8UI),
- ENUM_TO_STRING(R8I),
- ENUM_TO_STRING(R8),
- ENUM_TO_STRING(R32F),
- ENUM_TO_STRING(R32UI),
- ENUM_TO_STRING(R32I),
- ENUM_TO_STRING(R16F),
- ENUM_TO_STRING(R16UI),
- ENUM_TO_STRING(R16I),
- ENUM_TO_STRING(R16),
- ENUM_TO_STRING(R11F_G11F_B10F),
- ENUM_TO_STRING(SRGB8_ALPHA8),
- ENUM_TO_STRING(DEPTH24_STENCIL8),
- ENUM_TO_STRING(DEPTH32F_STENCIL8),
- ENUM_TO_STRING(DEPTH_COMPONENT32F),
- ENUM_TO_STRING(DEPTH_COMPONENT24),
- ENUM_TO_STRING(DEPTH_COMPONENT16),
+#define ENUM_TO_STRING(e) \
+ case GL_##e: { \
+ return STRINGIFY_ARG(e); \
+ }
+
+ switch (e) {
+ ENUM_TO_STRING(TEXTURE_CUBE_MAP);
+ ENUM_TO_STRING(TEXTURE_CUBE_MAP_ARRAY);
+ ENUM_TO_STRING(TEXTURE_2D);
+ ENUM_TO_STRING(TEXTURE_2D_ARRAY);
+ ENUM_TO_STRING(TEXTURE_1D);
+ ENUM_TO_STRING(TEXTURE_1D_ARRAY);
+ ENUM_TO_STRING(TEXTURE_3D);
+ ENUM_TO_STRING(TEXTURE_2D_MULTISAMPLE);
+ ENUM_TO_STRING(RGBA32F);
+ ENUM_TO_STRING(RGBA16F);
+ ENUM_TO_STRING(RGBA16UI);
+ ENUM_TO_STRING(RGBA16I);
+ ENUM_TO_STRING(RGBA16);
+ ENUM_TO_STRING(RGBA8UI);
+ ENUM_TO_STRING(RGBA8I);
+ ENUM_TO_STRING(RGBA8);
+ ENUM_TO_STRING(RGB16F);
+ ENUM_TO_STRING(RG32F);
+ ENUM_TO_STRING(RG16F);
+ ENUM_TO_STRING(RG16UI);
+ ENUM_TO_STRING(RG16I);
+ ENUM_TO_STRING(RG16);
+ ENUM_TO_STRING(RG8UI);
+ ENUM_TO_STRING(RG8I);
+ ENUM_TO_STRING(RG8);
+ ENUM_TO_STRING(R8UI);
+ ENUM_TO_STRING(R8I);
+ ENUM_TO_STRING(R8);
+ ENUM_TO_STRING(R32F);
+ ENUM_TO_STRING(R32UI);
+ ENUM_TO_STRING(R32I);
+ ENUM_TO_STRING(R16F);
+ ENUM_TO_STRING(R16UI);
+ ENUM_TO_STRING(R16I);
+ ENUM_TO_STRING(R16);
+ ENUM_TO_STRING(R11F_G11F_B10F);
+ ENUM_TO_STRING(SRGB8_ALPHA8);
+ ENUM_TO_STRING(DEPTH24_STENCIL8);
+ ENUM_TO_STRING(DEPTH32F_STENCIL8);
+ ENUM_TO_STRING(DEPTH_COMPONENT32F);
+ ENUM_TO_STRING(DEPTH_COMPONENT24);
+ ENUM_TO_STRING(DEPTH_COMPONENT16);
+ default:
+ return "Unkown enum";
};
#undef ENUM_TO_STRING
-
- return enum_strings[e];
}
static int gpu_get_component_count(eGPUTextureFormat format)
@@ -296,31 +312,28 @@ static eGPUDataFormat gpu_get_data_format_from_tex_format(eGPUTextureFormat tex_
if (ELEM(tex_format, GPU_DEPTH_COMPONENT24, GPU_DEPTH_COMPONENT16, GPU_DEPTH_COMPONENT32F)) {
return GPU_DATA_FLOAT;
}
- else if (ELEM(tex_format, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) {
+ if (ELEM(tex_format, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) {
return GPU_DATA_UNSIGNED_INT_24_8;
}
- else {
- /* Integer formats */
- if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) {
- if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
- return GPU_DATA_UNSIGNED_INT;
- }
- else {
- return GPU_DATA_INT;
- }
- }
- /* Byte formats */
- else if (ELEM(tex_format, GPU_R8)) {
- return GPU_DATA_UNSIGNED_BYTE;
- }
- /* Special case */
- else if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
- return GPU_DATA_10_11_11_REV;
- }
- else {
- return GPU_DATA_FLOAT;
+
+ /* Integer formats */
+ if (ELEM(tex_format, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R8UI, GPU_R16UI, GPU_R32UI)) {
+ if (ELEM(tex_format, GPU_R8UI, GPU_R16UI, GPU_RG16UI, GPU_R32UI)) {
+ return GPU_DATA_UNSIGNED_INT;
}
+
+ return GPU_DATA_INT;
+ }
+ /* Byte formats */
+ if (ELEM(tex_format, GPU_R8)) {
+ return GPU_DATA_UNSIGNED_BYTE;
+ }
+ /* Special case */
+ if (ELEM(tex_format, GPU_R11F_G11F_B10F)) {
+ return GPU_DATA_10_11_11_REV;
}
+
+ return GPU_DATA_FLOAT;
}
/* Definitely not complete, edit according to the gl specification. */
@@ -331,51 +344,50 @@ static GLenum gpu_get_gl_dataformat(eGPUTextureFormat data_type,
*format_flag |= GPU_FORMAT_DEPTH;
return GL_DEPTH_COMPONENT;
}
- else if (ELEM(data_type, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) {
+ if (ELEM(data_type, GPU_DEPTH24_STENCIL8, GPU_DEPTH32F_STENCIL8)) {
*format_flag |= GPU_FORMAT_DEPTH | GPU_FORMAT_STENCIL;
return GL_DEPTH_STENCIL;
}
- else {
- /* Integer formats */
- if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
- *format_flag |= GPU_FORMAT_INTEGER;
- switch (gpu_get_component_count(data_type)) {
- case 1:
- return GL_RED_INTEGER;
- break;
- case 2:
- return GL_RG_INTEGER;
- break;
- case 3:
- return GL_RGB_INTEGER;
- break;
- case 4:
- return GL_RGBA_INTEGER;
- break;
- }
- }
- else if (ELEM(data_type, GPU_R8)) {
- *format_flag |= GPU_FORMAT_FLOAT;
- return GL_RED;
+ /* Integer formats */
+ if (ELEM(data_type, GPU_R8UI, GPU_RG16I, GPU_R16I, GPU_RG16UI, GPU_R16UI, GPU_R32UI)) {
+ *format_flag |= GPU_FORMAT_INTEGER;
+
+ switch (gpu_get_component_count(data_type)) {
+ case 1:
+ return GL_RED_INTEGER;
+ break;
+ case 2:
+ return GL_RG_INTEGER;
+ break;
+ case 3:
+ return GL_RGB_INTEGER;
+ break;
+ case 4:
+ return GL_RGBA_INTEGER;
+ break;
}
- else {
- *format_flag |= GPU_FORMAT_FLOAT;
+ }
+ else if (ELEM(data_type, GPU_R8)) {
+ *format_flag |= GPU_FORMAT_FLOAT;
+ return GL_RED;
+ }
+ else {
+ *format_flag |= GPU_FORMAT_FLOAT;
- switch (gpu_get_component_count(data_type)) {
- case 1:
- return GL_RED;
- break;
- case 2:
- return GL_RG;
- break;
- case 3:
- return GL_RGB;
- break;
- case 4:
- return GL_RGBA;
- break;
- }
+ switch (gpu_get_component_count(data_type)) {
+ case 1:
+ return GL_RED;
+ break;
+ case 2:
+ return GL_RG;
+ break;
+ case 3:
+ return GL_RGB;
+ break;
+ case 4:
+ return GL_RGBA;
+ break;
}
}
@@ -423,6 +435,13 @@ static uint gpu_get_bytesize(eGPUTextureFormat data_type)
case GPU_R8:
case GPU_R8UI:
return 1;
+ case GPU_SRGB8_A8_DXT1:
+ case GPU_SRGB8_A8_DXT3:
+ case GPU_SRGB8_A8_DXT5:
+ case GPU_RGBA8_DXT1:
+ case GPU_RGBA8_DXT3:
+ case GPU_RGBA8_DXT5:
+ return 1; /* Incorrect but actual size is fractional. */
default:
BLI_assert(!"Texture format incorrect or unsupported\n");
return 0;
@@ -508,7 +527,18 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
case GPU_RGB16F:
return GL_RGB16F;
/* Special formats texture only */
- /* ** Add Format here */
+ case GPU_SRGB8_A8_DXT1:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
+ case GPU_SRGB8_A8_DXT3:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
+ case GPU_SRGB8_A8_DXT5:
+ return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
+ case GPU_RGBA8_DXT1:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case GPU_RGBA8_DXT3:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ case GPU_RGBA8_DXT5:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
/* Depth Formats */
case GPU_DEPTH_COMPONENT32F:
return GL_DEPTH_COMPONENT32F;
@@ -522,99 +552,6 @@ static GLenum gpu_format_to_gl_internalformat(eGPUTextureFormat format)
}
}
-static eGPUTextureFormat gl_internalformat_to_gpu_format(const GLint glformat)
-{
- /* You can add any of the available type to this list
- * For available types see GPU_texture.h */
- switch (glformat) {
- /* Formats texture & renderbuffer */
- case GL_RGBA8UI:
- return GPU_RGBA8UI;
- case GL_RGBA8I:
- return GPU_RGBA8I;
- case GL_RGBA8:
- return GPU_RGBA8;
- case GL_RGBA32UI:
- return GPU_RGBA32UI;
- case GL_RGBA32I:
- return GPU_RGBA32I;
- case GL_RGBA32F:
- return GPU_RGBA32F;
- case GL_RGBA16UI:
- return GPU_RGBA16UI;
- case GL_RGBA16I:
- return GPU_RGBA16I;
- case GL_RGBA16F:
- return GPU_RGBA16F;
- case GL_RGBA16:
- return GPU_RGBA16;
- case GL_RG8UI:
- return GPU_RG8UI;
- case GL_RG8I:
- return GPU_RG8I;
- case GL_RG8:
- return GPU_RG8;
- case GL_RG32UI:
- return GPU_RG32UI;
- case GL_RG32I:
- return GPU_RG32I;
- case GL_RG32F:
- return GPU_RG32F;
- case GL_RG16UI:
- return GPU_RG16UI;
- case GL_RG16I:
- return GPU_RG16I;
- case GL_RG16F:
- return GPU_RGBA32F;
- case GL_RG16:
- return GPU_RG16;
- case GL_R8UI:
- return GPU_R8UI;
- case GL_R8I:
- return GPU_R8I;
- case GL_R8:
- return GPU_R8;
- case GL_R32UI:
- return GPU_R32UI;
- case GL_R32I:
- return GPU_R32I;
- case GL_R32F:
- return GPU_R32F;
- case GL_R16UI:
- return GPU_R16UI;
- case GL_R16I:
- return GPU_R16I;
- case GL_R16F:
- return GPU_R16F;
- case GL_R16:
- return GPU_R16;
- /* Special formats texture & renderbuffer */
- case GL_R11F_G11F_B10F:
- return GPU_R11F_G11F_B10F;
- case GL_DEPTH32F_STENCIL8:
- return GPU_DEPTH32F_STENCIL8;
- case GL_DEPTH24_STENCIL8:
- return GPU_DEPTH24_STENCIL8;
- case GL_SRGB8_ALPHA8:
- return GPU_SRGB8_A8;
- /* Texture only format */
- case GL_RGB16F:
- return GPU_RGB16F;
- /* Special formats texture only */
- /* ** Add Format here */
- /* Depth Formats */
- case GL_DEPTH_COMPONENT32F:
- return GPU_DEPTH_COMPONENT32F;
- case GL_DEPTH_COMPONENT24:
- return GPU_DEPTH_COMPONENT24;
- case GL_DEPTH_COMPONENT16:
- return GPU_DEPTH_COMPONENT16;
- default:
- BLI_assert(!"Internal format incorrect or unsupported\n");
- }
- return -1;
-}
-
static GLenum gpu_get_gl_datatype(eGPUDataFormat format)
{
switch (format) {
@@ -640,8 +577,8 @@ static float *GPU_texture_rescale_3d(
GPUTexture *tex, int w, int h, int d, int channels, const float *fpixels)
{
const uint xf = w / tex->w, yf = h / tex->h, zf = d / tex->d;
- float *nfpixels = MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d,
- "GPUTexture Rescaled 3Dtex");
+ float *nfpixels = (float *)MEM_mallocN(channels * sizeof(float) * tex->w * tex->h * tex->d,
+ "GPUTexture Rescaled 3Dtex");
if (nfpixels) {
GPU_print_error_debug("You need to scale a 3D texture, feel the pain!");
@@ -726,31 +663,30 @@ static bool gpu_texture_check_capacity(
return true;
}
- else {
- switch (proxy) {
- case GL_PROXY_TEXTURE_1D:
- glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
- break;
- case GL_PROXY_TEXTURE_1D_ARRAY:
- case GL_PROXY_TEXTURE_2D:
- case GL_PROXY_TEXTURE_CUBE_MAP:
- glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
- break;
- case GL_PROXY_TEXTURE_2D_ARRAY:
- case GL_PROXY_TEXTURE_3D:
- glTexImage3D(
- proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
- break;
- case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
- glTexImage3D(
- proxy, 0, internalformat, tex->w, tex->h, tex->d * 6, 0, data_format, data_type, NULL);
- break;
- }
- int width = 0;
- glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width);
- return (width > 0);
+ switch (proxy) {
+ case GL_PROXY_TEXTURE_1D:
+ glTexImage1D(proxy, 0, internalformat, tex->w, 0, data_format, data_type, NULL);
+ break;
+ case GL_PROXY_TEXTURE_1D_ARRAY:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ glTexImage2D(proxy, 0, internalformat, tex->w, tex->h, 0, data_format, data_type, NULL);
+ break;
+ case GL_PROXY_TEXTURE_2D_ARRAY:
+ case GL_PROXY_TEXTURE_3D:
+ glTexImage3D(
+ proxy, 0, internalformat, tex->w, tex->h, tex->d, 0, data_format, data_type, NULL);
+ break;
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
+ glTexImage3D(
+ proxy, 0, internalformat, tex->w, tex->h, tex->d * 6, 0, data_format, data_type, NULL);
+ break;
}
+ int width = 0;
+ glGetTexLevelParameteriv(proxy, 0, GL_TEXTURE_WIDTH, &width);
+
+ return (width > 0);
}
/* This tries to allocate video memory for a given texture
@@ -836,7 +772,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex_format = GPU_DEPTH32F_STENCIL8;
}
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->w = w;
tex->h = h;
tex->d = d;
@@ -845,7 +781,7 @@ GPUTexture *GPU_texture_create_nD(int w,
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
tex->mipmaps = 0;
- tex->format_flag = 0;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
tex->number = -1;
if (n == 2) {
@@ -929,7 +865,7 @@ GPUTexture *GPU_texture_create_nD(int w,
data_type,
tex->components,
can_rescale,
- pixels,
+ (float *)pixels,
&rescaled_pixels);
if (G.debug & G_DEBUG_GPU || !valid) {
@@ -962,7 +898,7 @@ GPUTexture *GPU_texture_create_nD(int w,
gpu_texture_memory_footprint_add(tex);
/* Upload Texture */
- const float *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
+ const void *pix = (rescaled_pixels) ? rescaled_pixels : pixels;
if (tex->target == GL_TEXTURE_2D || tex->target == GL_TEXTURE_2D_MULTISAMPLE ||
tex->target == GL_TEXTURE_1D_ARRAY) {
@@ -1012,7 +948,7 @@ GPUTexture *GPU_texture_cube_create(int w,
eGPUDataFormat gpu_data_format,
char err_out[256])
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->w = w;
tex->h = w;
tex->d = d;
@@ -1161,11 +1097,11 @@ GPUTexture *GPU_texture_cube_create(int w,
/* Special buffer textures. tex_format must be compatible with the buffer content. */
GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint buffer)
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
tex->refcount = 1;
tex->format = tex_format;
tex->components = gpu_get_component_count(tex_format);
- tex->format_flag = 0;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
tex->target_base = tex->target = GL_TEXTURE_BUFFER;
tex->mipmaps = 0;
tex->number = -1;
@@ -1211,44 +1147,87 @@ GPUTexture *GPU_texture_create_buffer(eGPUTextureFormat tex_format, const GLuint
return tex;
}
-GPUTexture *GPU_texture_from_bindcode(int textarget, int bindcode)
+static GLenum convert_target_to_gl(int dimension, bool is_array)
{
- GPUTexture *tex = MEM_callocN(sizeof(GPUTexture), "GPUTexture");
- tex->bindcode = bindcode;
+ switch (dimension) {
+ case 1:
+ return is_array ? GL_TEXTURE_1D : GL_TEXTURE_1D_ARRAY;
+ case 2:
+ return is_array ? GL_TEXTURE_2D : GL_TEXTURE_2D_ARRAY;
+ case 3:
+ return GL_TEXTURE_3D;
+ default:
+ BLI_assert(0);
+ return GL_TEXTURE_2D;
+ }
+}
+
+/* Create an error texture that will bind an invalid texture (pink) at draw time. */
+GPUTexture *GPU_texture_create_error(int dimension, bool is_array)
+{
+ GLenum textarget = convert_target_to_gl(dimension, is_array);
+
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
+ tex->bindcode = 0;
tex->refcount = 1;
tex->target = textarget;
tex->target_base = textarget;
tex->samples = 0;
- tex->sampler_state = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO;
- if (GPU_get_mipmap()) {
- tex->sampler_state |= (GPU_SAMPLER_MIPMAP | GPU_SAMPLER_FILTER);
- }
+ tex->sampler_state = GPU_SAMPLER_DEFAULT;
tex->number = -1;
- if (!glIsTexture(tex->bindcode)) {
- GPU_print_error_debug("Blender Texture Not Loaded");
+ GPU_print_error_debug("Blender Texture Not Loaded");
+ return tex;
+}
+
+/* DDS texture loading. Return NULL if support is not available. */
+GPUTexture *GPU_texture_create_compressed(
+ int w, int h, int miplen, eGPUTextureFormat tex_format, const void *data)
+{
+ if (!GLEW_EXT_texture_compression_s3tc) {
+ return NULL;
}
- else {
- GLint w, h, gl_format;
- GLenum gettarget;
- gettarget = (textarget == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : textarget;
-
- glBindTexture(textarget, tex->bindcode);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_WIDTH, &w);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_HEIGHT, &h);
- glGetTexLevelParameteriv(gettarget, 0, GL_TEXTURE_INTERNAL_FORMAT, &gl_format);
- tex->w = w;
- tex->h = h;
- tex->format = gl_internalformat_to_gpu_format(gl_format);
- tex->components = gpu_get_component_count(tex->format);
- glBindTexture(textarget, 0);
-
- /* Depending on how this bindcode was obtained, the memory used here could
- * already have been computed.
- * But that is not the case currently. */
- gpu_texture_memory_footprint_add(tex);
+
+ GPUTexture *tex = (GPUTexture *)MEM_callocN(sizeof(GPUTexture), __func__);
+ tex->w = w;
+ tex->h = h;
+ tex->refcount = 1;
+ tex->target = tex->target_base = GL_TEXTURE_2D;
+ tex->format_flag = static_cast<eGPUTextureFormatFlag>(0);
+ tex->components = gpu_get_component_count(tex_format);
+ tex->mipmaps = miplen - 1;
+ tex->sampler_state = GPU_SAMPLER_DEFAULT;
+ tex->number = -1;
+
+ GLenum internalformat = gpu_format_to_gl_internalformat(tex_format);
+
+ glGenTextures(1, &tex->bindcode);
+ glBindTexture(tex->target, tex->bindcode);
+
+ /* Reset to opengl Defaults. (Untested, might not be needed) */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+
+ int blocksize = (ELEM(tex_format, GPU_RGBA8_DXT1, GPU_SRGB8_A8_DXT1)) ? 8 : 16;
+
+ size_t ofs = 0;
+ for (int mip = 0; mip < miplen && (w || h); mip++, w >>= 1, h >>= 1) {
+ w = max_ii(1, w);
+ h = max_ii(1, h);
+ size_t size = ((w + 3) / 4) * ((h + 3) / 4) * blocksize;
+
+ glCompressedTexImage2D(tex->target, mip, internalformat, w, h, 0, size, (uchar *)data + ofs);
+
+ ofs += size;
}
+ /* Restore Blender default. */
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ glTexParameteri(tex->target, GL_TEXTURE_MAX_LEVEL, tex->mipmaps);
+ glTexParameteri(tex->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glBindTexture(tex->target, 0);
+
return tex;
}
@@ -1503,7 +1482,8 @@ void GPU_texture_update_sub(GPUTexture *tex,
GLenum data_format = gpu_get_gl_dataformat(tex->format, &tex->format_flag);
GLenum data_type = gpu_get_gl_datatype(gpu_data_format);
- glBindTexture(tex->target, tex->bindcode);
+ WARN_NOT_BOUND(tex);
+
switch (tex->target) {
case GL_TEXTURE_1D:
glTexSubImage1D(tex->target, 0, offset_x, width, data_format, data_type, pixels);
@@ -1531,8 +1511,6 @@ void GPU_texture_update_sub(GPUTexture *tex,
default:
BLI_assert(!"tex->target mode not supported");
}
-
- glBindTexture(tex->target, 0);
}
void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat gpu_data_format, int miplvl)
@@ -1826,16 +1804,6 @@ void GPU_texture_unbind_all(void)
glActiveTexture(GL_TEXTURE0);
}
-#define WARN_NOT_BOUND(_tex) \
- { \
- if (_tex->number == -1) { \
- fprintf(stderr, "Warning : Trying to set parameter on a texture not bound.\n"); \
- BLI_assert(0); \
- return; \
- } \
- } \
- ((void)0)
-
void GPU_texture_generate_mipmap(GPUTexture *tex)
{
WARN_NOT_BOUND(tex);
@@ -1979,6 +1947,14 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
SET_FLAG_FROM_TEST(tex->sampler_state, use_filter, GPU_SAMPLER_FILTER);
}
+void GPU_texture_anisotropic_filter(GPUTexture *tex, bool use_aniso)
+{
+ /* Stencil and integer format does not support filtering. */
+ BLI_assert(!(use_aniso) || !(GPU_texture_stencil(tex) || GPU_texture_integer(tex)));
+
+ SET_FLAG_FROM_TEST(tex->sampler_state, use_aniso, GPU_SAMPLER_ANISO);
+}
+
void GPU_texture_wrap_mode(GPUTexture *tex, bool use_repeat, bool use_clamp)
{
SET_FLAG_FROM_TEST(tex->sampler_state, use_repeat, GPU_SAMPLER_REPEAT);
@@ -2193,7 +2169,7 @@ void GPU_samplers_init(void)
{
glGenSamplers(GPU_SAMPLER_MAX, GG.samplers);
for (int i = 0; i < GPU_SAMPLER_MAX; i++) {
- eGPUSamplerState state = i;
+ eGPUSamplerState state = static_cast<eGPUSamplerState>(i);
GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE;
GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type;
GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type;
@@ -2203,8 +2179,9 @@ void GPU_samplers_init(void)
((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) :
((state & GPU_SAMPLER_MIPMAP) ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST);
GLenum compare_mode = (state & GPU_SAMPLER_COMPARE) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
+ /* TODO(fclem) Anisotropic level should be a render engine parameter. */
float aniso_filter = ((state & GPU_SAMPLER_MIPMAP) && (state & GPU_SAMPLER_ANISO)) ?
- GPU_get_anisotropic() :
+ U.anisotropic_filter :
1.0f;
glSamplerParameteri(GG.samplers[i], GL_TEXTURE_WRAP_S, wrap_s);
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.cc
index 130e8fe7da1..f0724ce7c9a 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.cc
@@ -25,6 +25,7 @@
#include <string.h>
#include "BLI_blenlib.h"
+#include "BLI_math_base.h"
#include "gpu_context_private.h"
#include "gpu_node_graph.h"
@@ -34,217 +35,63 @@
#include "GPU_material.h"
#include "GPU_uniformbuffer.h"
-typedef enum eGPUUniformBufferFlag {
- GPU_UBO_FLAG_INITIALIZED = (1 << 0),
- GPU_UBO_FLAG_DIRTY = (1 << 1),
-} eGPUUniformBufferFlag;
-
-typedef enum eGPUUniformBufferType {
- GPU_UBO_STATIC = 0,
- GPU_UBO_DYNAMIC = 1,
-} eGPUUniformBufferType;
-
-struct GPUUniformBuffer {
- int size; /* in bytes */
- GLuint bindcode; /* opengl identifier for UBO */
- int bindpoint; /* current binding point */
- eGPUUniformBufferType type;
-};
-
-#define GPUUniformBufferStatic GPUUniformBuffer
-
-typedef struct GPUUniformBufferDynamic {
- GPUUniformBuffer buffer;
- void *data; /* Continuous memory block to copy to GPU. */
- char flag;
-} GPUUniformBufferDynamic;
-
-/* Prototypes */
-static eGPUType get_padded_gpu_type(struct LinkData *link);
-static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
-
-/* Only support up to this type, if you want to extend it, make sure the
- * padding logic is correct for the new types. */
-#define MAX_UBO_GPU_TYPE GPU_MAT4
-
-static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data)
-{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferData(GL_UNIFORM_BUFFER, ubo->size, data, GL_DYNAMIC_DRAW);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-}
+typedef struct GPUUniformBuffer {
+ /** Data size in bytes. */
+ int size;
+ /** GL handle for UBO. */
+ GLuint bindcode;
+ /** Current binding point. */
+ int bindpoint;
+ /** Continuous memory block to copy to GPU. Is own by the GPUUniformBuffer. */
+ void *data;
+} GPUUniformBuffer;
GPUUniformBuffer *GPU_uniformbuffer_create(int size, const void *data, char err_out[256])
{
/* Make sure that UBO is padded to size of vec4 */
BLI_assert((size % 16) == 0);
- GPUUniformBuffer *ubo = MEM_callocN(sizeof(GPUUniformBufferStatic), "GPUUniformBufferStatic");
- ubo->size = size;
- ubo->bindpoint = -1;
-
- /* Generate Buffer object */
- ubo->bindcode = GPU_buf_alloc();
-
- if (!ubo->bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- if (ubo->size > GPU_max_ubo_size()) {
+ if (size > GPU_max_ubo_size()) {
if (err_out) {
BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
}
- GPU_uniformbuffer_free(ubo);
- return NULL;
- }
-
- gpu_uniformbuffer_initialize(ubo, data);
- return ubo;
-}
-
-/**
- * Create dynamic UBO from parameters
- * Return NULL if failed to create or if \param inputs: is empty.
- *
- * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
- */
-GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256])
-{
- /* There is no point on creating an UBO if there is no arguments. */
- if (BLI_listbase_is_empty(inputs)) {
return NULL;
}
- GPUUniformBufferDynamic *ubo = MEM_callocN(sizeof(GPUUniformBufferDynamic),
- "GPUUniformBufferDynamic");
- ubo->buffer.type = GPU_UBO_DYNAMIC;
- ubo->buffer.bindpoint = -1;
- ubo->flag = GPU_UBO_FLAG_DIRTY;
-
- /* Generate Buffer object. */
- ubo->buffer.bindcode = GPU_buf_alloc();
-
- if (!ubo->buffer.bindcode) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO create failed", 256);
- }
- GPU_uniformbuffer_free(&ubo->buffer);
- return NULL;
- }
-
- if (ubo->buffer.size > GPU_max_ubo_size()) {
- if (err_out) {
- BLI_strncpy(err_out, "GPUUniformBuffer: UBO too big", 256);
- }
- GPU_uniformbuffer_free(&ubo->buffer);
- return NULL;
- }
-
- /* Make sure we comply to the ubo alignment requirements. */
- gpu_uniformbuffer_inputs_sort(inputs);
-
- LISTBASE_FOREACH (LinkData *, link, inputs) {
- const eGPUType gputype = get_padded_gpu_type(link);
- ubo->buffer.size += gputype * sizeof(float);
- }
-
- /* Round up to size of vec4 */
- ubo->buffer.size = ((ubo->buffer.size + 15) / 16) * 16;
-
- /* Allocate the data. */
- ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
+ GPUUniformBuffer *ubo = (GPUUniformBuffer *)MEM_mallocN(sizeof(GPUUniformBuffer), __func__);
+ ubo->size = size;
+ ubo->data = NULL;
+ ubo->bindcode = 0;
+ ubo->bindpoint = -1;
- /* Now that we know the total ubo size we can start populating it. */
- float *offset = ubo->data;
- LISTBASE_FOREACH (LinkData *, link, inputs) {
- GPUInput *input = link->data;
- memcpy(offset, input->vec, input->type * sizeof(float));
- offset += get_padded_gpu_type(link);
+ /* Direct init. */
+ if (data != NULL) {
+ GPU_uniformbuffer_update(ubo, data);
}
- /* Note since we may create the UBOs in the CPU in a different thread than the main drawing one,
- * we don't create the UBO in the GPU here. This will happen when we first bind the UBO.
- */
-
- return &ubo->buffer;
-}
-
-/**
- * Free the data
- */
-static void gpu_uniformbuffer_dynamic_free(GPUUniformBuffer *ubo_)
-{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
-
- ubo->buffer.size = 0;
- if (ubo->data) {
- MEM_freeN(ubo->data);
- }
+ return ubo;
}
void GPU_uniformbuffer_free(GPUUniformBuffer *ubo)
{
- if (ubo->type == GPU_UBO_DYNAMIC) {
- gpu_uniformbuffer_dynamic_free(ubo);
- }
-
+ MEM_SAFE_FREE(ubo->data);
GPU_buf_free(ubo->bindcode);
MEM_freeN(ubo);
}
-static void gpu_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
-{
- glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
- glBindBuffer(GL_UNIFORM_BUFFER, 0);
-}
-
-void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
-{
- BLI_assert(ubo->type == GPU_UBO_STATIC);
- gpu_uniformbuffer_update(ubo, data);
-}
-
-/**
- * We need to recalculate the internal data, and re-generate it
- * from its populated items.
- */
-void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
-{
- BLI_assert(ubo_->type == GPU_UBO_DYNAMIC);
- GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
-
- if (ubo->flag & GPU_UBO_FLAG_INITIALIZED) {
- gpu_uniformbuffer_update(ubo_, ubo->data);
- }
- else {
- ubo->flag |= GPU_UBO_FLAG_INITIALIZED;
- gpu_uniformbuffer_initialize(ubo_, ubo->data);
- }
-
- ubo->flag &= ~GPU_UBO_FLAG_DIRTY;
-}
-
/**
* We need to pad some data types (vec3) on the C side
* To match the GPU expected memory block alignment.
*/
static eGPUType get_padded_gpu_type(LinkData *link)
{
- GPUInput *input = link->data;
+ GPUInput *input = (GPUInput *)link->data;
eGPUType gputype = input->type;
-
/* Unless the vec3 is followed by a float we need to treat it as a vec4. */
if (gputype == GPU_VEC3 && (link->next != NULL) &&
(((GPUInput *)link->next->data)->type != GPU_FLOAT)) {
gputype = GPU_VEC4;
}
-
return gputype;
}
@@ -254,8 +101,9 @@ static eGPUType get_padded_gpu_type(LinkData *link)
*/
static int inputs_cmp(const void *a, const void *b)
{
- const LinkData *link_a = a, *link_b = b;
- const GPUInput *input_a = link_a->data, *input_b = link_b->data;
+ const LinkData *link_a = (const LinkData *)a, *link_b = (const LinkData *)b;
+ const GPUInput *input_a = (const GPUInput *)link_a->data;
+ const GPUInput *input_b = (const GPUInput *)link_b->data;
return input_a->type < input_b->type ? 1 : 0;
}
@@ -265,22 +113,26 @@ static int inputs_cmp(const void *a, const void *b)
*/
static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
{
+/* Only support up to this type, if you want to extend it, make sure the
+ * padding logic is correct for the new types. */
+#define MAX_UBO_GPU_TYPE GPU_MAT4
+
/* Order them as mat4, vec4, vec3, vec2, float. */
BLI_listbase_sort(inputs, inputs_cmp);
/* Creates a lookup table for the different types; */
LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL};
- eGPUType cur_type = MAX_UBO_GPU_TYPE + 1;
+ eGPUType cur_type = static_cast<eGPUType>(MAX_UBO_GPU_TYPE + 1);
LISTBASE_FOREACH (LinkData *, link, inputs) {
- GPUInput *input = link->data;
+ GPUInput *input = (GPUInput *)link->data;
if (input->type == GPU_MAT3) {
/* Alignment for mat3 is not handled currently, so not supported */
BLI_assert(!"mat3 not supported in UBO");
continue;
}
- else if (input->type > MAX_UBO_GPU_TYPE) {
+ if (input->type > MAX_UBO_GPU_TYPE) {
BLI_assert(!"GPU type not supported in UBO");
continue;
}
@@ -288,10 +140,9 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
if (input->type == cur_type) {
continue;
}
- else {
- inputs_lookup[input->type] = link;
- cur_type = input->type;
- }
+
+ inputs_lookup[input->type] = link;
+ cur_type = input->type;
}
/* If there is no GPU_VEC3 there is no need for alignment. */
@@ -319,6 +170,74 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
link = link_next;
}
+#undef MAX_UBO_GPU_TYPE
+}
+
+/**
+ * Create dynamic UBO from parameters
+ * Return NULL if failed to create or if \param inputs: is empty.
+ *
+ * \param inputs: ListBase of #BLI_genericNodeN(#GPUInput).
+ */
+GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_out[256])
+{
+ /* There is no point on creating an UBO if there is no arguments. */
+ if (BLI_listbase_is_empty(inputs)) {
+ return NULL;
+ }
+ /* Make sure we comply to the ubo alignment requirements. */
+ gpu_uniformbuffer_inputs_sort(inputs);
+
+ size_t buffer_size = 0;
+
+ LISTBASE_FOREACH (LinkData *, link, inputs) {
+ const eGPUType gputype = get_padded_gpu_type(link);
+ buffer_size += gputype * sizeof(float);
+ }
+ /* Round up to size of vec4. (Opengl Requirement) */
+ size_t alignment = sizeof(float[4]);
+ buffer_size = divide_ceil_u(buffer_size, alignment) * alignment;
+ void *data = MEM_mallocN(buffer_size, __func__);
+
+ /* Now that we know the total ubo size we can start populating it. */
+ float *offset = (float *)data;
+ LISTBASE_FOREACH (LinkData *, link, inputs) {
+ GPUInput *input = (GPUInput *)link->data;
+ memcpy(offset, input->vec, input->type * sizeof(float));
+ offset += get_padded_gpu_type(link);
+ }
+
+ /* Pass data as NULL for late init. */
+ GPUUniformBuffer *ubo = GPU_uniformbuffer_create(buffer_size, NULL, err_out);
+ /* Data will be update just before binding. */
+ ubo->data = data;
+ return ubo;
+}
+
+static void gpu_uniformbuffer_init(GPUUniformBuffer *ubo)
+{
+ BLI_assert(ubo->bindcode == 0);
+ ubo->bindcode = GPU_buf_alloc();
+
+ if (ubo->bindcode == 0) {
+ fprintf(stderr, "GPUUniformBuffer: UBO create failed");
+ BLI_assert(0);
+ return;
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferData(GL_UNIFORM_BUFFER, ubo->size, NULL, GL_DYNAMIC_DRAW);
+}
+
+void GPU_uniformbuffer_update(GPUUniformBuffer *ubo, const void *data)
+{
+ if (ubo->bindcode == 0) {
+ gpu_uniformbuffer_init(ubo);
+ }
+
+ glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
+ glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo->size, data);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
@@ -328,28 +247,30 @@ void GPU_uniformbuffer_bind(GPUUniformBuffer *ubo, int number)
return;
}
- if (ubo->type == GPU_UBO_DYNAMIC) {
- GPUUniformBufferDynamic *ubo_dynamic = (GPUUniformBufferDynamic *)ubo;
- if (ubo_dynamic->flag & GPU_UBO_FLAG_DIRTY) {
- GPU_uniformbuffer_dynamic_update(ubo);
- }
+ if (ubo->bindcode == 0) {
+ gpu_uniformbuffer_init(ubo);
}
- if (ubo->bindcode != 0) {
- glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
+ if (ubo->data != NULL) {
+ GPU_uniformbuffer_update(ubo, ubo->data);
+ MEM_SAFE_FREE(ubo->data);
}
+ glBindBufferBase(GL_UNIFORM_BUFFER, number, ubo->bindcode);
ubo->bindpoint = number;
}
void GPU_uniformbuffer_unbind(GPUUniformBuffer *ubo)
{
- ubo->bindpoint = -1;
+#ifndef NDEBUG
+ glBindBufferBase(GL_UNIFORM_BUFFER, ubo->bindpoint, 0);
+#endif
+ ubo->bindpoint = 0;
}
-int GPU_uniformbuffer_bindpoint(GPUUniformBuffer *ubo)
+void GPU_uniformbuffer_unbind_all(void)
{
- return ubo->bindpoint;
+ for (int i = 0; i < GPU_max_ubo_binds(); i++) {
+ glBindBufferBase(GL_UNIFORM_BUFFER, i, 0);
+ }
}
-
-#undef MAX_UBO_GPU_TYPE
diff --git a/source/blender/gpu/intern/gpu_vertex_buffer.c b/source/blender/gpu/intern/gpu_vertex_buffer.cc
index 3b4d469542c..eda6d1c7300 100644
--- a/source/blender/gpu/intern/gpu_vertex_buffer.c
+++ b/source/blender/gpu/intern/gpu_vertex_buffer.cc
@@ -39,17 +39,22 @@ static uint vbo_memory_usage;
static GLenum convert_usage_type_to_gl(GPUUsageType type)
{
- static const GLenum table[] = {
- [GPU_USAGE_STREAM] = GL_STREAM_DRAW,
- [GPU_USAGE_STATIC] = GL_STATIC_DRAW,
- [GPU_USAGE_DYNAMIC] = GL_DYNAMIC_DRAW,
- };
- return table[type];
+ switch (type) {
+ case GPU_USAGE_STREAM:
+ return GL_STREAM_DRAW;
+ case GPU_USAGE_DYNAMIC:
+ return GL_DYNAMIC_DRAW;
+ case GPU_USAGE_STATIC:
+ return GL_STATIC_DRAW;
+ default:
+ BLI_assert(0);
+ return GL_STATIC_DRAW;
+ }
}
GPUVertBuf *GPU_vertbuf_create(GPUUsageType usage)
{
- GPUVertBuf *verts = MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf");
+ GPUVertBuf *verts = (GPUVertBuf *)MEM_mallocN(sizeof(GPUVertBuf), "GPUVertBuf");
GPU_vertbuf_init(verts, usage);
return verts;
}
@@ -109,7 +114,7 @@ GPUVertBuf *GPU_vertbuf_duplicate(GPUVertBuf *verts)
}
if (verts->data) {
- verts_dst->data = MEM_dupallocN(verts->data);
+ verts_dst->data = (uchar *)MEM_dupallocN(verts->data);
}
return verts_dst;
}
@@ -161,7 +166,7 @@ void GPU_vertbuf_data_alloc(GPUVertBuf *verts, uint v_len)
#endif
verts->dirty = true;
verts->vertex_len = verts->vertex_alloc = v_len;
- verts->data = MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), "GPUVertBuf data");
+ verts->data = (uchar *)MEM_mallocN(sizeof(GLubyte) * GPU_vertbuf_size_get(verts), __func__);
}
/* resize buffer keeping existing data */
@@ -178,7 +183,7 @@ void GPU_vertbuf_data_resize(GPUVertBuf *verts, uint v_len)
#endif
verts->dirty = true;
verts->vertex_len = verts->vertex_alloc = v_len;
- verts->data = MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts));
+ verts->data = (uchar *)MEM_reallocN(verts->data, sizeof(GLubyte) * GPU_vertbuf_size_get(verts));
}
/* Set vertex count but does not change allocation.
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.cc
index 585a22277b2..2e8017660d0 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -63,21 +63,29 @@ void GPU_vertformat_copy(GPUVertFormat *dest, const GPUVertFormat *src)
memcpy(dest, src, sizeof(GPUVertFormat));
}
-static GLenum convert_comp_type_to_gl(GPUVertCompType type)
+GLenum convert_comp_type_to_gl(GPUVertCompType type)
{
- static const GLenum table[] = {
- [GPU_COMP_I8] = GL_BYTE,
- [GPU_COMP_U8] = GL_UNSIGNED_BYTE,
- [GPU_COMP_I16] = GL_SHORT,
- [GPU_COMP_U16] = GL_UNSIGNED_SHORT,
- [GPU_COMP_I32] = GL_INT,
- [GPU_COMP_U32] = GL_UNSIGNED_INT,
-
- [GPU_COMP_F32] = GL_FLOAT,
-
- [GPU_COMP_I10] = GL_INT_2_10_10_10_REV,
- };
- return table[type];
+ switch (type) {
+ case GPU_COMP_I8:
+ return GL_BYTE;
+ case GPU_COMP_U8:
+ return GL_UNSIGNED_BYTE;
+ case GPU_COMP_I16:
+ return GL_SHORT;
+ case GPU_COMP_U16:
+ return GL_UNSIGNED_SHORT;
+ case GPU_COMP_I32:
+ return GL_INT;
+ case GPU_COMP_U32:
+ return GL_UNSIGNED_INT;
+ case GPU_COMP_F32:
+ return GL_FLOAT;
+ case GPU_COMP_I10:
+ return GL_INT_2_10_10_10_REV;
+ default:
+ BLI_assert(0);
+ return GL_FLOAT;
+ }
}
static uint comp_sz(GPUVertCompType type)
@@ -94,7 +102,7 @@ static uint attr_sz(const GPUVertAttr *a)
if (a->comp_type == GPU_COMP_I10) {
return 4; /* always packed as 10_10_10_2 */
}
- return a->comp_len * comp_sz(a->comp_type);
+ return a->comp_len * comp_sz(static_cast<GPUVertCompType>(a->comp_type));
}
static uint attr_align(const GPUVertAttr *a)
@@ -102,13 +110,12 @@ static uint attr_align(const GPUVertAttr *a)
if (a->comp_type == GPU_COMP_I10) {
return 4; /* always packed as 10_10_10_2 */
}
- uint c = comp_sz(a->comp_type);
+ uint c = comp_sz(static_cast<GPUVertCompType>(a->comp_type));
if (a->comp_len == 3 && c <= 2) {
return 4 * c; /* AMD HW can't fetch these well, so pad it out (other vendors too?) */
}
- else {
- return c; /* most fetches are ok if components are naturally aligned */
- }
+
+ return c; /* most fetches are ok if components are naturally aligned */
}
uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len)
@@ -185,7 +192,6 @@ uint GPU_vertformat_attr_add(GPUVertFormat *format,
attr->names[attr->name_len++] = copy_attr_name(format, name);
attr->comp_type = comp_type;
- attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
attr->comp_len = (comp_type == GPU_COMP_I10) ?
4 :
comp_len; /* system needs 10_10_10_2 to be 4 or BGRA */
@@ -279,7 +285,7 @@ void GPU_vertformat_attr_rename(GPUVertFormat *format, int attr_id, const char *
/* Encode 8 original bytes into 11 safe bytes. */
static void safe_bytes(char out[11], const char data[8])
{
- char safe_chars[63] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
+ char safe_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
uint64_t in = *(uint64_t *)data;
for (int i = 0; i < 11; i++) {
@@ -368,14 +374,6 @@ static void show_pack(uint a_idx, uint sz, uint pad)
void VertexFormat_pack(GPUVertFormat *format)
{
- /* For now, attributes are packed in the order they were added,
- * making sure each attribute is naturally aligned (add padding where necessary)
- * Later we can implement more efficient packing w/ reordering
- * (keep attribute ID order, adjust their offsets to reorder in buffer). */
-
- /* TODO: realloc just enough to hold the final combo string. And just enough to
- * hold used attributes, not all 16. */
-
GPUVertAttr *a0 = &format->attrs[0];
a0->offset = 0;
uint offset = a0->sz;
@@ -512,7 +510,6 @@ void GPU_vertformat_from_shader(GPUVertFormat *format, const GPUShader *shader)
attr->sz = attr->comp_len * 4;
attr->fetch_mode = fetch_mode;
attr->comp_type = comp_type;
- attr->gl_comp_type = convert_comp_type_to_gl(comp_type);
attr += 1;
}
}
diff --git a/source/blender/gpu/intern/gpu_vertex_format_private.h b/source/blender/gpu/intern/gpu_vertex_format_private.h
index a80c085b44a..45523c0e956 100644
--- a/source/blender/gpu/intern/gpu_vertex_format_private.h
+++ b/source/blender/gpu/intern/gpu_vertex_format_private.h
@@ -25,6 +25,15 @@
#pragma once
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void VertexFormat_pack(GPUVertFormat *format);
uint padding(uint offset, uint alignment);
uint vertex_buffer_size(const GPUVertFormat *format, uint vertex_len);
+GLenum convert_comp_type_to_gl(GPUVertCompType type);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c
index 7f133ca626d..ba938349761 100644
--- a/source/blender/gpu/intern/gpu_viewport.c
+++ b/source/blender/gpu/intern/gpu_viewport.c
@@ -38,7 +38,6 @@
#include "DNA_vec_types.h"
#include "GPU_framebuffer.h"
-#include "GPU_glew.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_texture.h"
@@ -913,9 +912,8 @@ GPUTexture *GPU_viewport_color_texture(GPUViewport *viewport, int view)
if (viewport->active_view == view) {
return dtxl->color;
}
- else {
- return dtxl->color_stereo;
- }
+
+ return dtxl->color_stereo;
}
return NULL;
diff --git a/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
new file mode 100644
index 00000000000..f7bf3d33361
--- /dev/null
+++ b/source/blender/gpu/shaders/gpu_shader_codegen_lib.glsl
@@ -0,0 +1,87 @@
+
+vec3 calc_barycentric_distances(vec3 pos0, vec3 pos1, vec3 pos2)
+{
+ vec3 edge21 = pos2 - pos1;
+ vec3 edge10 = pos1 - pos0;
+ vec3 edge02 = pos0 - pos2;
+ vec3 d21 = normalize(edge21);
+ vec3 d10 = normalize(edge10);
+ vec3 d02 = normalize(edge02);
+
+ vec3 dists;
+ float d = dot(d21, edge02);
+ dists.x = sqrt(dot(edge02, edge02) - d * d);
+ d = dot(d02, edge10);
+ dists.y = sqrt(dot(edge10, edge10) - d * d);
+ d = dot(d10, edge21);
+ dists.z = sqrt(dot(edge21, edge21) - d * d);
+ return dists;
+}
+
+vec2 calc_barycentric_co(int vertid)
+{
+ vec2 bary;
+ bary.x = float((vertid % 3) == 0);
+ bary.y = float((vertid % 3) == 1);
+ return bary;
+}
+
+#ifdef HAIR_SHADER
+
+/* Hairs uv and col attributes are passed by bufferTextures. */
+# define DEFINE_ATTR(type, attr) uniform samplerBuffer attr
+# define GET_ATTR(type, attr) hair_get_customdata_##type(attr)
+
+# define barycentric_get() hair_get_barycentric()
+# define barycentric_resolve(bary) hair_resolve_barycentric(bary)
+
+vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], const samplerBuffer orco_samp)
+{
+ /* TODO: fix ORCO with modifiers. */
+ vec3 orco = (modelmatinv * vec4(local_pos, 1.0)).xyz;
+ return orco_madd[0].xyz + orco * orco_madd[1].xyz;
+}
+
+vec4 tangent_get(const samplerBuffer attr, mat3 normalmat)
+{
+ /* Unsupported */
+ return vec4(0.0);
+}
+
+#else /* MESH_SHADER */
+
+# define DEFINE_ATTR(type, attr) in type attr
+# define GET_ATTR(type, attr) attr
+
+/* Calculated in geom shader later with calc_barycentric_co. */
+# define barycentric_get() vec2(0)
+# define barycentric_resolve(bary) bary
+
+vec3 orco_get(vec3 local_pos, mat4 modelmatinv, vec4 orco_madd[2], vec4 orco)
+{
+ /* If the object does not have any deformation, the orco layer calculation is done on the fly
+ * using the orco_madd factors.
+ * We know when there is no orco layer when orco.w is 1.0 because it uses the generic vertex
+ * attrib (which is [0,0,0,1]). */
+ if (orco.w == 0.0) {
+ return orco.xyz * 0.5 + 0.5;
+ }
+ else {
+ return orco_madd[0].xyz + local_pos * orco_madd[1].xyz;
+ }
+}
+
+vec4 tangent_get(vec4 attr, mat3 normalmat)
+{
+ vec4 tangent;
+ tangent.xyz = normalmat * attr.xyz;
+ tangent.w = attr.w;
+ float len_sqr = dot(tangent.xyz, tangent.xyz);
+ /* Normalize only if vector is not null. */
+ if (len_sqr > 0.0) {
+ tangent.xyz *= inversesqrt(len_sqr);
+ }
+ return tangent;
+}
+
+#endif
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
index d6d6fbab971..eea8d19efce 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_ambient_occlusion.glsl
@@ -3,7 +3,7 @@ void node_ambient_occlusion(
vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
{
vec3 bent_normal;
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
result_color = result_ao * color;
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
index 3b23ac976ae..6330daa4391 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl
@@ -1,3 +1,15 @@
+
+float wang_hash_noise(uint s)
+{
+ s = (s ^ 61u) ^ (s >> 16u);
+ s *= 9u;
+ s = s ^ (s >> 4u);
+ s *= 0x27d4eb2du;
+ s = s ^ (s >> 15u);
+
+ return fract(float(s) / 4294967296.0);
+}
+
void node_hair_info(out float is_strand,
out float intercept,
out float thickness,
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
index f9691beee6f..d33465fa846 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_world_normals.glsl
@@ -6,7 +6,7 @@ void world_normals_get(out vec3 N)
vec3 B = normalize(cross(worldNormal, hairTangent));
float cos_theta;
if (hairThicknessRes == 1) {
- vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy);
/* Random cosine normal distribution on the hair surface. */
cos_theta = rand.x * 2.0 - 1.0;
}
diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h
index fa7d7ff555c..674b384adf2 100644
--- a/source/blender/ikplugin/BIK_api.h
+++ b/source/blender/ikplugin/BIK_api.h
@@ -35,10 +35,10 @@ struct bConstraint;
struct bPose;
struct bPoseChannel;
-void BIK_initialize_tree(struct Depsgraph *depsgraph,
- struct Scene *scene,
- struct Object *ob,
- float ctime);
+void BIK_init_tree(struct Depsgraph *depsgraph,
+ struct Scene *scene,
+ struct Object *ob,
+ float ctime);
void BIK_execute_tree(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob,
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 5e683d36408..233150a77aa 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -80,7 +80,7 @@ static IKPlugin *get_plugin(bPose *pose)
/*----------------------------------------*/
/* Plugin API */
-void BIK_initialize_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
+void BIK_init_tree(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime)
{
IKPlugin *plugin = get_plugin(ob->pose);
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 3646686e81f..ba096653e0f 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -452,21 +452,20 @@ static void execute_posetree(struct Depsgraph *depsgraph,
/* don't solve IK when we are setting the pole angle */
break;
}
- else {
- mul_m4_m4m4(goal, goalinv, rootmat);
- copy_v3_v3(polepos, goal[3]);
- poleconstrain = 1;
-
- /* for pole targets, we blend the result of the ik solver
- * instead of the target position, otherwise we can't get
- * a smooth transition */
- resultblend = 1;
- resultinf = target->con->enforce;
-
- if (data->flag & CONSTRAINT_IK_GETANGLE) {
- poleangledata = data;
- data->flag &= ~CONSTRAINT_IK_GETANGLE;
- }
+
+ mul_m4_m4m4(goal, goalinv, rootmat);
+ copy_v3_v3(polepos, goal[3]);
+ poleconstrain = 1;
+
+ /* for pole targets, we blend the result of the ik solver
+ * instead of the target position, otherwise we can't get
+ * a smooth transition */
+ resultblend = 1;
+ resultinf = target->con->enforce;
+
+ if (data->flag & CONSTRAINT_IK_GETANGLE) {
+ poleangledata = data;
+ data->flag &= ~CONSTRAINT_IK_GETANGLE;
}
}
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 8f84d04f602..a5fdb9ef491 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -446,24 +446,21 @@ static double EulerAngleFromMatrix(const KDL::Rotation &R, int axis)
if (axis == 0) {
return -KDL::atan2(R(1, 2), R(2, 2));
}
- else if (axis == 1) {
+ if (axis == 1) {
return KDL::atan2(-R(0, 2), t);
}
- else {
- return -KDL::atan2(R(0, 1), R(0, 0));
- }
+
+ return -KDL::atan2(R(0, 1), R(0, 0));
}
- else {
- if (axis == 0) {
- return -KDL::atan2(-R(2, 1), R(1, 1));
- }
- else if (axis == 1) {
- return KDL::atan2(-R(0, 2), t);
- }
- else {
- return 0.0f;
- }
+
+ if (axis == 0) {
+ return -KDL::atan2(-R(2, 1), R(1, 1));
+ }
+ if (axis == 1) {
+ return KDL::atan2(-R(0, 2), t);
}
+
+ return 0.0f;
}
static double ComputeTwist(const KDL::Rotation &R)
diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt
index cad0be659ec..cf637a06405 100644
--- a/source/blender/imbuf/CMakeLists.txt
+++ b/source/blender/imbuf/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../blenkernel
../blenlib
../blenloader
+ ../gpu
../makesdna
../makesrna
../../../intern/guardedalloc
@@ -63,6 +64,7 @@ set(SRC
intern/thumbs_blend.c
intern/thumbs_font.c
intern/util.c
+ intern/util_gpu.c
intern/writeimage.c
IMB_colormanagement.h
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 0f3d121ff96..37046521dd8 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -89,6 +89,12 @@ struct Stereo3dFormat;
/**
*
+ * \attention defined in GPU_texture.h
+ */
+struct GPUTexture;
+
+/**
+ *
* \attention Defined in allocimbuf.c
*/
void IMB_init(void);
@@ -728,6 +734,25 @@ const char *IMB_ffmpeg_last_error(void);
/**
*
+ * \attention defined in util_gpu.c
+ */
+struct GPUTexture *IMB_create_gpu_texture(struct ImBuf *ibuf,
+ bool use_high_bitdepth,
+ bool use_premult);
+struct GPUTexture *IMB_touch_gpu_texture(
+ struct ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth);
+void IMB_update_gpu_texture_sub(struct GPUTexture *tex,
+ struct ImBuf *ibuf,
+ int x,
+ int y,
+ int z,
+ int w,
+ int h,
+ bool use_high_bitdepth,
+ bool use_premult);
+
+/**
+ *
* \attention defined in stereoimbuf.c
*/
void IMB_stereo3d_write_dimensions(const char mode,
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 4b3858e6d5a..4205a6ecc39 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -423,9 +423,8 @@ bool imb_addrectImBuf(ImBuf *ibuf)
if (ibuf->planes > 32) {
return (addzbufImBuf(ibuf));
}
- else {
- return true;
- }
+
+ return true;
}
return false;
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 9fab450cc76..01372d5ed68 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -803,7 +803,7 @@ static void ffmpeg_postprocess(struct anim *anim)
if (ENDIAN_ORDER == B_ENDIAN) {
int *dstStride = anim->pFrameRGB->linesize;
uint8_t **dst = anim->pFrameRGB->data;
- int dstStride2[4] = {dstStride[0], 0, 0, 0};
+ const int dstStride2[4] = {dstStride[0], 0, 0, 0};
uint8_t *dst2[4] = {dst[0], 0, 0, 0};
int x, y, h, w;
unsigned char *bottom;
@@ -849,7 +849,7 @@ static void ffmpeg_postprocess(struct anim *anim)
else {
int *dstStride = anim->pFrameRGB->linesize;
uint8_t **dst = anim->pFrameRGB->data;
- int dstStride2[4] = {-dstStride[0], 0, 0, 0};
+ const int dstStride2[4] = {-dstStride[0], 0, 0, 0};
uint8_t *dst2[4] = {dst[0] + (anim->y - 1) * dstStride[0], 0, 0, 0};
sws_scale(anim->img_convert_ctx,
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index e9030496498..362a558b505 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -119,7 +119,7 @@ LogImageFile *logImageOpenFromFile(const char *filename, int cineon)
if (logImageIsDpx(&magicNum)) {
return dpxOpen((const unsigned char *)filename, 0, 0);
}
- else if (logImageIsCineon(&magicNum)) {
+ if (logImageIsCineon(&magicNum)) {
return cineonOpen((const unsigned char *)filename, 0, 0);
}
@@ -131,7 +131,7 @@ LogImageFile *logImageOpenFromMemory(const unsigned char *buffer, unsigned int s
if (logImageIsDpx(buffer)) {
return dpxOpen(buffer, 1, size);
}
- else if (logImageIsCineon(buffer)) {
+ if (logImageIsCineon(buffer)) {
return cineonOpen(buffer, 1, size);
}
@@ -154,18 +154,17 @@ LogImageFile *logImageCreate(const char *filename,
if (cineon) {
return cineonCreate(filename, width, height, bitsPerSample, creator);
}
- else {
- return dpxCreate(filename,
- width,
- height,
- bitsPerSample,
- isLogarithmic,
- hasAlpha,
- referenceWhite,
- referenceBlack,
- gamma,
- creator);
- }
+
+ return dpxCreate(filename,
+ width,
+ height,
+ bitsPerSample,
+ isLogarithmic,
+ hasAlpha,
+ referenceWhite,
+ referenceBlack,
+ gamma,
+ creator);
return NULL;
}
@@ -1677,7 +1676,7 @@ static int convertLogElementToRGBA(
if (rvalue == 1) {
return 1;
}
- else if (dstIsLinearRGB) {
+ if (dstIsLinearRGB) {
/* convert data from sRGB to Linear RGB via lut */
float *lut = getSrgbToLinLut(logElement);
src_ptr = dst; // no error here
diff --git a/source/blender/imbuf/intern/cineon/logmemfile.c b/source/blender/imbuf/intern/cineon/logmemfile.c
index 91351d309de..aca84df91ca 100644
--- a/source/blender/imbuf/intern/cineon/logmemfile.c
+++ b/source/blender/imbuf/intern/cineon/logmemfile.c
@@ -64,10 +64,9 @@ int logimage_fwrite(void *buffer, size_t size, unsigned int count, LogImageFile
if (logFile->file) {
return fwrite(buffer, size, count, logFile->file);
}
- else { /* we're writing to memory */
- /* do nothing as this isn't supported yet */
- return count;
- }
+ /* we're writing to memory */
+ /* do nothing as this isn't supported yet */
+ return count;
}
int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *logFile)
@@ -75,23 +74,22 @@ int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *
if (logFile->file) {
return fread(buffer, size, count, logFile->file);
}
- else { /* we're reading from memory */
- unsigned char *buf = (unsigned char *)buffer;
- uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
- size_t total_size = size * count;
- if (pos + total_size > logFile->memBufferSize) {
- /* how many elements can we read without overflow ? */
- count = (logFile->memBufferSize - pos) / size;
- /* recompute the size */
- total_size = size * count;
- }
-
- if (total_size != 0) {
- memcpy(buf, logFile->memCursor, total_size);
- }
+ /* we're reading from memory */
+ unsigned char *buf = (unsigned char *)buffer;
+ uintptr_t pos = (uintptr_t)logFile->memCursor - (uintptr_t)logFile->memBuffer;
+ size_t total_size = size * count;
+ if (pos + total_size > logFile->memBufferSize) {
+ /* how many elements can we read without overflow ? */
+ count = (logFile->memBufferSize - pos) / size;
+ /* recompute the size */
+ total_size = size * count;
+ }
- return count;
+ if (total_size != 0) {
+ memcpy(buf, logFile->memCursor, total_size);
}
+
+ return count;
}
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile)
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index c9b3db39976..08e1bc5f674 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1399,9 +1399,8 @@ const char *IMB_colormanagement_get_float_colorspace(ImBuf *ibuf)
if (ibuf->float_colorspace) {
return ibuf->float_colorspace->name;
}
- else {
- return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
- }
+
+ return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
}
const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
@@ -1409,9 +1408,8 @@ const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
if (ibuf->rect_colorspace) {
return ibuf->rect_colorspace->name;
}
- else {
- return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
- }
+
+ return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
}
bool IMB_colormanagement_space_is_data(ColorSpace *colorspace)
@@ -3958,7 +3956,7 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
{
int i;
- BKE_curvemapping_initialize(curve_mapping);
+ BKE_curvemapping_init(curve_mapping);
BKE_curvemapping_premultiply(curve_mapping, false);
BKE_curvemapping_table_RGBA(
curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index 9fd6d71e091..1fbe7b46963 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -97,21 +97,20 @@ uint BlockDXT1::evaluatePalette(Color32 color_array[4]) const
return 4;
}
- else {
- // Three-color block: derive the other color.
- color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
- color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
- color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
- color_array[2].a = 0xFF;
- // Set all components to 0 to match DXT specs.
- color_array[3].r = 0x00; // color_array[2].r;
- color_array[3].g = 0x00; // color_array[2].g;
- color_array[3].b = 0x00; // color_array[2].b;
- color_array[3].a = 0x00;
+ // Three-color block: derive the other color.
+ color_array[2].r = (color_array[0].r + color_array[1].r) / 2;
+ color_array[2].g = (color_array[0].g + color_array[1].g) / 2;
+ color_array[2].b = (color_array[0].b + color_array[1].b) / 2;
+ color_array[2].a = 0xFF;
- return 3;
- }
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
}
uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
@@ -143,21 +142,20 @@ uint BlockDXT1::evaluatePaletteNV5x(Color32 color_array[4]) const
return 4;
}
- else {
- // Three-color block: derive the other color.
- color_array[2].r = ((col0.r + col1.r) * 33) / 8;
- color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
- color_array[2].b = ((col0.b + col1.b) * 33) / 8;
- color_array[2].a = 0xFF;
- // Set all components to 0 to match DXT specs.
- color_array[3].r = 0x00; // color_array[2].r;
- color_array[3].g = 0x00; // color_array[2].g;
- color_array[3].b = 0x00; // color_array[2].b;
- color_array[3].a = 0x00;
+ // Three-color block: derive the other color.
+ color_array[2].r = ((col0.r + col1.r) * 33) / 8;
+ color_array[2].g = (256 * color_array[0].g + gdiff / 4 + 128 + gdiff * 128) / 256;
+ color_array[2].b = ((col0.b + col1.b) * 33) / 8;
+ color_array[2].a = 0xFF;
- return 3;
- }
+ // Set all components to 0 to match DXT specs.
+ color_array[3].r = 0x00; // color_array[2].r;
+ color_array[3].g = 0x00; // color_array[2].g;
+ color_array[3].b = 0x00; // color_array[2].b;
+ color_array[3].a = 0x00;
+
+ return 3;
}
// Evaluate palette assuming 3 color block.
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index 9730153819e..92dd475813a 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -864,9 +864,8 @@ uint DDSHeader::d3d9Format() const
if (pf.flags & DDPF_FOURCC) {
return pf.fourcc;
}
- else {
- return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
- }
+
+ return findD3D9Format(pf.bitcount, pf.rmask, pf.gmask, pf.bmask, pf.amask);
}
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
@@ -923,33 +922,32 @@ bool DirectDrawSurface::isSupported() const
return false;
}
- else {
- if (header.pf.flags & DDPF_FOURCC) {
- if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 &&
- header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 &&
- header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB &&
- header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) {
- // Unknown fourcc code.
- return false;
- }
- }
- else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) {
- // All RGB and luminance formats are supported now.
- }
- else {
- return false;
- }
- if (isTextureCube() &&
- (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) {
- // Cubemaps must contain all faces.
+ if (header.pf.flags & DDPF_FOURCC) {
+ if (header.pf.fourcc != FOURCC_DXT1 && header.pf.fourcc != FOURCC_DXT2 &&
+ header.pf.fourcc != FOURCC_DXT3 && header.pf.fourcc != FOURCC_DXT4 &&
+ header.pf.fourcc != FOURCC_DXT5 && header.pf.fourcc != FOURCC_RXGB &&
+ header.pf.fourcc != FOURCC_ATI1 && header.pf.fourcc != FOURCC_ATI2) {
+ // Unknown fourcc code.
return false;
}
+ }
+ else if ((header.pf.flags & DDPF_RGB) || (header.pf.flags & DDPF_LUMINANCE)) {
+ // All RGB and luminance formats are supported now.
+ }
+ else {
+ return false;
+ }
- if (isTexture3D()) {
- // @@ 3D textures not supported yet.
- return false;
- }
+ if (isTextureCube() &&
+ (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES) {
+ // Cubemaps must contain all faces.
+ return false;
+ }
+
+ if (isTexture3D()) {
+ // @@ 3D textures not supported yet.
+ return false;
}
return true;
@@ -963,23 +961,21 @@ bool DirectDrawSurface::hasAlpha() const
header.header10.dxgiFormat == DXGI_FORMAT_BC2_UNORM ||
header.header10.dxgiFormat == DXGI_FORMAT_BC3_UNORM;
}
- else {
- if (header.pf.flags & DDPF_RGB) {
- return header.pf.amask != 0;
- }
- else if (header.pf.flags & DDPF_FOURCC) {
- if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 ||
- header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) {
- return false;
- }
- else {
- // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
- return true;
- }
+
+ if (header.pf.flags & DDPF_RGB) {
+ return header.pf.amask != 0;
+ }
+ if (header.pf.flags & DDPF_FOURCC) {
+ if (header.pf.fourcc == FOURCC_RXGB || header.pf.fourcc == FOURCC_ATI1 ||
+ header.pf.fourcc == FOURCC_ATI2 || header.pf.flags & DDPF_NORMAL) {
+ return false;
}
- return false;
+ // @@ Here we could check the ALPHA_PIXELS flag, but nobody sets it. (except us?)
+ return true;
}
+
+ return false;
}
uint DirectDrawSurface::mipmapCount() const
@@ -987,9 +983,8 @@ uint DirectDrawSurface::mipmapCount() const
if (header.flags & DDSD_MIPMAPCOUNT) {
return header.mipmapcount;
}
- else {
- return 1;
- }
+
+ return 1;
}
uint DirectDrawSurface::fourCC() const
@@ -1002,9 +997,8 @@ uint DirectDrawSurface::width() const
if (header.flags & DDSD_WIDTH) {
return header.width;
}
- else {
- return 1;
- }
+
+ return 1;
}
uint DirectDrawSurface::height() const
@@ -1012,9 +1006,8 @@ uint DirectDrawSurface::height() const
if (header.flags & DDSD_HEIGHT) {
return header.height;
}
- else {
- return 1;
- }
+
+ return 1;
}
uint DirectDrawSurface::depth() const
@@ -1022,9 +1015,8 @@ uint DirectDrawSurface::depth() const
if (header.flags & DDSD_DEPTH) {
return header.depth;
}
- else {
- return 1;
- }
+
+ return 1;
}
bool DirectDrawSurface::isTexture1D() const
@@ -1040,9 +1032,8 @@ bool DirectDrawSurface::isTexture2D() const
if (header.hasDX10Header()) {
return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D;
}
- else {
- return !isTexture3D() && !isTextureCube();
- }
+
+ return !isTexture3D() && !isTextureCube();
}
bool DirectDrawSurface::isTexture3D() const
@@ -1050,9 +1041,8 @@ bool DirectDrawSurface::isTexture3D() const
if (header.hasDX10Header()) {
return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D;
}
- else {
- return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
- }
+
+ return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
}
bool DirectDrawSurface::isTextureCube() const
@@ -1355,16 +1345,15 @@ uint DirectDrawSurface::mipmapSize(uint mipmap) const
h = (h + 3) / 4;
return blockSize() * w * h;
}
- else if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) {
+ if (header.pf.flags & DDPF_RGB || (header.pf.flags & DDPF_LUMINANCE)) {
uint pitch = computePitch(
w, header.pf.bitcount, 8); // Assuming 8 bit alignment, which is the same D3DX expects.
return pitch * h * d;
}
- else {
- printf("DDS: mipmap format not supported\n");
- return (0);
- }
+
+ printf("DDS: mipmap format not supported\n");
+ return (0);
}
uint DirectDrawSurface::faceSize() const
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index f5c937654b3..f46f50eb2b9 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -217,7 +217,7 @@ int FlipDXTCImage(
// no flip to do, and we're done.
break;
}
- else if (mip_height == 2) {
+ if (mip_height == 2) {
// flip the first 2 lines in each block.
for (unsigned int i = 0; i < blocks_per_row; i++) {
half_block_function(data + i * block_bytes);
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index d8a5096af71..12f90f27309 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -394,9 +394,8 @@ static int filter_make_index(const int x, const int y, const int w, const int h)
if (x < 0 || x >= w || y < 0 || y >= h) {
return -1; /* return bad index */
}
- else {
- return y * w + x;
- }
+
+ return y * w + x;
}
static int check_pixel_assigned(
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 7cc31b99077..dd2edebedff 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -268,9 +268,8 @@ int IMB_indexer_get_frame_index(struct anim_index *idx, int frameno)
if (first == idx->num_entries) {
return idx->num_entries - 1;
}
- else {
- return first;
- }
+
+ return first;
}
unsigned long long IMB_indexer_get_pts(struct anim_index *idx, int frame_index)
@@ -633,9 +632,8 @@ static int add_to_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, AVFrame *fra
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static void free_proxy_output_ffmpeg(struct proxy_output_ctx *ctx, int rollback)
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 2516df22151..5f698543aa9 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -892,10 +892,9 @@ static int output_iris(uint *lptr, int xsize, int ysize, int zsize, const char *
if (goodwrite) {
return 1;
}
- else {
- fprintf(stderr, "output_iris: not enough space for image!!\n");
- return 0;
- }
+
+ fprintf(stderr, "output_iris: not enough space for image!!\n");
+ return 0;
}
/* static utility functions for output_iris */
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 5154f50c7e8..a5b977be2ce 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -73,12 +73,11 @@ static OPJ_CODEC_FORMAT format_from_header(const unsigned char mem[JP2_FILEHEADE
if (check_jp2(mem)) {
return OPJ_CODEC_JP2;
}
- else if (check_j2k(mem)) {
+ if (check_j2k(mem)) {
return OPJ_CODEC_J2K;
}
- else {
- return OPJ_CODEC_UNKNOWN;
- }
+
+ return OPJ_CODEC_UNKNOWN;
}
int imb_is_a_jp2(const unsigned char *buf)
@@ -339,16 +338,14 @@ ImBuf *imb_load_jp2_filepath(const char *filepath, int flags, char colorspace[IM
if (stream) {
return NULL;
}
- else {
- if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) {
- opj_stream_destroy(stream);
- return NULL;
- }
- else {
- fseek(p_file, 0, SEEK_SET);
- }
+
+ if (fread(mem, sizeof(mem), 1, p_file) != sizeof(mem)) {
+ opj_stream_destroy(stream);
+ return NULL;
}
+ fseek(p_file, 0, SEEK_SET);
+
const OPJ_CODEC_FORMAT format = format_from_header(mem);
ImBuf *ibuf = imb_load_jp2_stream(stream, format, flags, colorspace);
opj_stream_destroy(stream);
@@ -651,7 +648,7 @@ BLI_INLINE int DOWNSAMPLE_FLOAT_TO_16BIT(const float _val)
#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
-static int initialise_4K_poc(opj_poc_t *POC, int numres)
+static int init_4K_poc(opj_poc_t *POC, int numres)
{
POC[0].tile = 1;
POC[0].resno0 = 0;
@@ -750,7 +747,7 @@ static void cinema_setup_encoder(opj_cparameters_t *parameters,
else {
parameters->cp_rsiz = DCP_CINEMA2K;
}
- parameters->numpocs = initialise_4K_poc(parameters->POC, parameters->numresolution);
+ parameters->numpocs = init_4K_poc(parameters->POC, parameters->numresolution);
break;
case OPJ_OFF:
/* do nothing */
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index 96ecbdce9cc..f7b033869e3 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -192,9 +192,8 @@ static size_t get_size_in_memory(ImBuf *ibuf)
if (ibuf->userflags & IB_PERSISTENT) {
return 0;
}
- else {
- return IMB_get_size_in_memory(ibuf);
- }
+
+ return IMB_get_size_in_memory(ibuf);
}
static size_t get_item_size(void *p)
{
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 9b614eab0dc..05592a7d408 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -131,9 +131,8 @@ class IMemStream : public Imf::IStream {
_exrpos += n;
return true;
}
- else {
- return false;
- }
+
+ return false;
}
virtual Int64 tellg()
@@ -597,15 +596,13 @@ int imb_save_openexr(struct ImBuf *ibuf, const char *name, int flags)
if (ibuf->foptions.flag & OPENEXR_HALF) {
return (int)imb_save_openexr_half(ibuf, name, flags);
}
- else {
- /* when no float rect, we save as half (16 bits is sufficient) */
- if (ibuf->rect_float == NULL) {
- return (int)imb_save_openexr_half(ibuf, name, flags);
- }
- else {
- return (int)imb_save_openexr_float(ibuf, name, flags);
- }
+
+ /* when no float rect, we save as half (16 bits is sufficient) */
+ if (ibuf->rect_float == NULL) {
+ return (int)imb_save_openexr_half(ibuf, name, flags);
}
+
+ return (int)imb_save_openexr_float(ibuf, name, flags);
}
/* ******* Nicer API, MultiLayer and with Tile file support ************************************ */
@@ -719,9 +716,8 @@ static int imb_exr_get_multiView_id(StringVector &views, const std::string &name
if (name == *i) {
return count;
}
- else {
- count++;
- }
+
+ count++;
}
/* no views or wrong name */
@@ -741,7 +737,7 @@ static void imb_exr_get_views(MultiPartInputFile &file, StringVector &views)
else {
for (int p = 0; p < file.parts(); p++) {
- std::string view = "";
+ std::string view;
if (file.header(p).hasView()) {
view = file.header(p).view();
}
@@ -1421,7 +1417,7 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
printf("multilayer read: bad channel name: %s\n", name);
return 0;
}
- else if (len == 1) {
+ if (len == 1) {
echan->chan_id = token[0];
}
else if (len > 1) {
diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c
index 5569e119b95..247122065de 100644
--- a/source/blender/imbuf/intern/stereoimbuf.c
+++ b/source/blender/imbuf/intern/stereoimbuf.c
@@ -669,17 +669,17 @@ static void imb_stereo3d_squeeze_rect(
/*************************** preparing to call the write functions **************************/
-static void imb_stereo3d_data_initialize(Stereo3DData *s3d_data,
- const bool is_float,
- const size_t x,
- const size_t y,
- const size_t channels,
- int *rect_left,
- int *rect_right,
- int *rect_stereo,
- float *rectf_left,
- float *rectf_right,
- float *rectf_stereo)
+static void imb_stereo3d_data_init(Stereo3DData *s3d_data,
+ const bool is_float,
+ const size_t x,
+ const size_t y,
+ const size_t channels,
+ int *rect_left,
+ int *rect_right,
+ int *rect_stereo,
+ float *rectf_left,
+ float *rectf_right,
+ float *rectf_stereo)
{
s3d_data->is_float = is_float;
s3d_data->x = x;
@@ -709,7 +709,7 @@ int *IMB_stereo3d_from_rect(ImageFormatData *im_format,
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
r_rect = MEM_mallocN(channels * sizeof(int) * width * height, __func__);
- imb_stereo3d_data_initialize(
+ imb_stereo3d_data_init(
&s3d_data, is_float, x, y, channels, rect_left, rect_right, r_rect, NULL, NULL, NULL);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_rect(r_rect, &im_format->stereo3d_format, x, y, channels);
@@ -733,7 +733,7 @@ float *IMB_stereo3d_from_rectf(ImageFormatData *im_format,
im_format->stereo3d_format.display_mode, false, x, y, &width, &height);
r_rectf = MEM_mallocN(channels * sizeof(float) * width * height, __func__);
- imb_stereo3d_data_initialize(
+ imb_stereo3d_data_init(
&s3d_data, is_float, x, y, channels, NULL, NULL, NULL, rectf_left, rectf_right, r_rectf);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_rectf(r_rectf, &im_format->stereo3d_format, x, y, channels);
@@ -759,17 +759,17 @@ ImBuf *IMB_stereo3d_ImBuf(ImageFormatData *im_format, ImBuf *ibuf_left, ImBuf *i
ibuf_stereo->flags = ibuf_left->flags;
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 4,
- (int *)ibuf_left->rect,
- (int *)ibuf_right->rect,
- (int *)ibuf_stereo->rect,
- ibuf_left->rect_float,
- ibuf_right->rect_float,
- ibuf_stereo->rect_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo->rect_float);
imb_stereo3d_write_doit(&s3d_data, &im_format->stereo3d_format);
imb_stereo3d_squeeze_ImBuf(ibuf_stereo, &im_format->stereo3d_format, ibuf_left->x, ibuf_left->y);
@@ -1286,17 +1286,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d,
&height);
imb_stereo3d_unsqueeze_ImBuf(ibuf_stereo3d, s3d, width, height);
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 4,
- (int *)ibuf_left->rect,
- (int *)ibuf_right->rect,
- (int *)ibuf_stereo3d->rect,
- ibuf_left->rect_float,
- ibuf_right->rect_float,
- ibuf_stereo3d->rect_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 4,
+ (int *)ibuf_left->rect,
+ (int *)ibuf_right->rect,
+ (int *)ibuf_stereo3d->rect,
+ ibuf_left->rect_float,
+ ibuf_right->rect_float,
+ ibuf_stereo3d->rect_float);
imb_stereo3d_read_doit(&s3d_data, s3d);
@@ -1310,17 +1310,17 @@ void IMB_ImBufFromStereo3d(Stereo3dFormat *s3d,
addzbufImBuf(ibuf_right);
}
- imb_stereo3d_data_initialize(&s3d_data,
- is_float,
- ibuf_left->x,
- ibuf_left->y,
- 1,
- (int *)ibuf_left->zbuf,
- (int *)ibuf_right->zbuf,
- (int *)ibuf_stereo3d->zbuf,
- ibuf_left->zbuf_float,
- ibuf_right->zbuf_float,
- ibuf_stereo3d->zbuf_float);
+ imb_stereo3d_data_init(&s3d_data,
+ is_float,
+ ibuf_left->x,
+ ibuf_left->y,
+ 1,
+ (int *)ibuf_left->zbuf,
+ (int *)ibuf_right->zbuf,
+ (int *)ibuf_stereo3d->zbuf,
+ ibuf_left->zbuf_float,
+ ibuf_right->zbuf_float,
+ ibuf_stereo3d->zbuf_float);
imb_stereo3d_read_doit(&s3d_data, s3d);
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 715f2aaf621..5d72066675b 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -306,8 +306,8 @@ static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char *
#define IMB_TIFF_NCB 4 /* number of comparison bytes used */
int imb_is_a_tiff(const unsigned char *mem)
{
- char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a};
- char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00};
+ const char big_endian[IMB_TIFF_NCB] = {0x4d, 0x4d, 0x00, 0x2a};
+ const char lil_endian[IMB_TIFF_NCB] = {0x49, 0x49, 0x2a, 0x00};
return ((memcmp(big_endian, mem, IMB_TIFF_NCB) == 0) ||
(memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0));
@@ -792,16 +792,16 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
"not yet supported.\n");
return (0);
}
- else {
- /* create image as a file */
+
+ /* create image as a file */
#ifdef WIN32
- wchar_t *wname = alloc_utf16_from_8(name, 0);
- image = TIFFOpenW(wname, "w");
- free(wname);
+ wchar_t *wname = alloc_utf16_from_8(name, 0);
+ image = TIFFOpenW(wname, "w");
+ free(wname);
#else
- image = TIFFOpen(name, "w");
+ image = TIFFOpen(name, "w");
#endif
- }
+
if (image == NULL) {
fprintf(stderr, "imb_savetiff: could not open TIFF for writing.\n");
return (0);
diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c
new file mode 100644
index 00000000000..1a46572fb20
--- /dev/null
+++ b/source/blender/imbuf/intern/util_gpu.c
@@ -0,0 +1,260 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ * util.c
+ */
+
+/** \file
+ * \ingroup imbuf
+ */
+
+#include "imbuf.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "MEM_guardedalloc.h"
+
+#include "BKE_global.h"
+
+#include "GPU_extensions.h"
+#include "GPU_texture.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+/* gpu ibuf utils */
+
+static void imb_gpu_get_format(const ImBuf *ibuf,
+ bool high_bitdepth,
+ eGPUDataFormat *r_data_format,
+ eGPUTextureFormat *r_texture_format)
+{
+ const bool float_rect = (ibuf->rect_float != NULL);
+ const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) &&
+ !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
+ high_bitdepth = (!(ibuf->flags & IB_halffloat) && high_bitdepth);
+
+ *r_data_format = (float_rect) ? GPU_DATA_FLOAT : GPU_DATA_UNSIGNED_BYTE;
+
+ if (float_rect) {
+ *r_texture_format = high_bitdepth ? GPU_RGBA32F : GPU_RGBA16F;
+ }
+ else {
+ *r_texture_format = use_srgb ? GPU_SRGB8_A8 : GPU_RGBA8;
+ }
+}
+
+/* Return false if no suitable format was found. */
+#ifdef WITH_DDS
+static bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, eGPUTextureFormat *r_texture_format)
+{
+ /* For DDS we only support data, scene linear and sRGB. Converting to
+ * different colorspace would break the compression. */
+ const bool use_srgb = (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace) &&
+ !IMB_colormanagement_space_is_scene_linear(ibuf->rect_colorspace));
+
+ if (ibuf->dds_data.fourcc == FOURCC_DXT1) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT1 : GPU_RGBA8_DXT1;
+ }
+ else if (ibuf->dds_data.fourcc == FOURCC_DXT3) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT3 : GPU_RGBA8_DXT3;
+ }
+ else if (ibuf->dds_data.fourcc == FOURCC_DXT5) {
+ *r_texture_format = (use_srgb) ? GPU_SRGB8_A8_DXT5 : GPU_RGBA8_DXT5;
+ }
+ else {
+ return false;
+ }
+ return true;
+}
+#endif
+
+/**
+ * Apply colormanagement and scale buffer if needed.
+ * *r_freedata is set to true if the returned buffer need to be manually freed.
+ **/
+static void *imb_gpu_get_data(const ImBuf *ibuf,
+ const bool do_rescale,
+ const int rescale_size[2],
+ const bool compress_as_srgb,
+ const bool store_premultiplied,
+ bool *r_freedata)
+{
+ const bool is_float_rect = (ibuf->rect_float != NULL);
+ void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect;
+
+ if (is_float_rect) {
+ /* Float image is already in scene linear colorspace or non-color data by
+ * convention, no colorspace conversion needed. But we do require 4 channels
+ * currently. */
+ if (ibuf->channels != 4 || !store_premultiplied) {
+ data_rect = MEM_mallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, __func__);
+ *r_freedata = true;
+
+ if (data_rect == NULL) {
+ return NULL;
+ }
+
+ IMB_colormanagement_imbuf_to_float_texture(
+ (float *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, store_premultiplied);
+ }
+ }
+ else {
+ /* Byte image is in original colorspace from the file. If the file is sRGB
+ * scene linear, or non-color data no conversion is needed. Otherwise we
+ * compress as scene linear + sRGB transfer function to avoid precision loss
+ * in common cases.
+ *
+ * We must also convert to premultiplied for correct texture interpolation
+ * and consistency with float images. */
+ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) {
+ data_rect = MEM_mallocN(sizeof(uchar) * 4 * ibuf->x * ibuf->y, __func__);
+ *r_freedata = true;
+
+ if (data_rect == NULL) {
+ return NULL;
+ }
+
+ /* Texture storage of images is defined by the alpha mode of the image. The
+ * downside of this is that there can be artifacts near alpha edges. However,
+ * this allows us to use sRGB texture formats and preserves color values in
+ * zero alpha areas, and appears generally closer to what game engines that we
+ * want to be compatible with do. */
+ IMB_colormanagement_imbuf_to_byte_texture(
+ (uchar *)data_rect, 0, 0, ibuf->x, ibuf->y, ibuf, compress_as_srgb, store_premultiplied);
+ }
+ }
+
+ if (do_rescale) {
+ uint *rect = (is_float_rect) ? NULL : (uint *)data_rect;
+ float *rect_float = (is_float_rect) ? (float *)data_rect : NULL;
+
+ ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4);
+ IMB_scaleImBuf(scale_ibuf, UNPACK2(rescale_size));
+
+ data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect;
+ *r_freedata = true;
+ /* Steal the rescaled buffer to avoid double free. */
+ scale_ibuf->rect_float = NULL;
+ scale_ibuf->rect = NULL;
+ IMB_freeImBuf(scale_ibuf);
+ }
+ return data_rect;
+}
+
+/* The ibuf is only here to detect the storage type. The produced texture will have undefined
+ * content. It will need to be populated by using IMB_update_gpu_texture_sub(). */
+GPUTexture *IMB_touch_gpu_texture(ImBuf *ibuf, int w, int h, int layers, bool use_high_bitdepth)
+{
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ GPUTexture *tex = GPU_texture_create_nD(
+ w, h, layers, 2, NULL, tex_format, data_format, 0, false, NULL);
+
+ GPU_texture_anisotropic_filter(tex, true);
+ return tex;
+}
+
+/* Will update a GPUTexture using the content of the ImBuf. Only one layer will be updated.
+ * Will resize the ibuf if needed.
+ * z is the layer to update. Unused if the texture is 2D. */
+void IMB_update_gpu_texture_sub(GPUTexture *tex,
+ ImBuf *ibuf,
+ int x,
+ int y,
+ int z,
+ int w,
+ int h,
+ bool use_high_bitdepth,
+ bool use_premult)
+{
+ const bool do_rescale = (ibuf->x != w || ibuf->y != h);
+ const int size[2] = {w, h};
+
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8);
+ bool freebuf = false;
+
+ void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf);
+
+ /* Update Texture. */
+ GPU_texture_update_sub(tex, data_format, data, x, y, z, w, h, 1);
+
+ if (freebuf) {
+ MEM_freeN(data);
+ }
+}
+
+GPUTexture *IMB_create_gpu_texture(ImBuf *ibuf, bool use_high_bitdepth, bool use_premult)
+{
+ GPUTexture *tex = NULL;
+ const int size[2] = {GPU_texture_size_with_limit(ibuf->x), GPU_texture_size_with_limit(ibuf->y)};
+ bool do_rescale = (ibuf->x != size[0]) || (ibuf->y != size[1]);
+
+#ifdef WITH_DDS
+ if (ibuf->ftype == IMB_FTYPE_DDS) {
+ eGPUTextureFormat compressed_format;
+ if (!IMB_gpu_get_compressed_format(ibuf, &compressed_format)) {
+ fprintf(stderr, "Unable to find a suitable DXT compression,");
+ }
+ else if (do_rescale) {
+ fprintf(stderr, "Unable to load DXT image resolution,");
+ }
+ else if (!is_power_of_2_i(ibuf->x) || !is_power_of_2_i(ibuf->y)) {
+ fprintf(stderr, "Unable to load non-power-of-two DXT image resolution,");
+ }
+ else {
+ tex = GPU_texture_create_compressed(
+ ibuf->x, ibuf->y, ibuf->dds_data.nummipmaps, compressed_format, ibuf->dds_data.data);
+
+ if (tex != NULL) {
+ return tex;
+ }
+
+ fprintf(stderr, "ST3C support not found,");
+ }
+ /* Fallback to uncompressed texture. */
+ fprintf(stderr, " falling back to uncompressed.\n");
+ }
+#endif
+
+ eGPUDataFormat data_format;
+ eGPUTextureFormat tex_format;
+ imb_gpu_get_format(ibuf, use_high_bitdepth, &data_format, &tex_format);
+
+ const bool compress_as_srgb = (tex_format == GPU_SRGB8_A8);
+ bool freebuf = false;
+
+ void *data = imb_gpu_get_data(ibuf, do_rescale, size, compress_as_srgb, use_premult, &freebuf);
+
+ /* Create Texture. */
+ tex = GPU_texture_create_nD(UNPACK2(size), 0, 2, data, tex_format, data_format, 0, false, NULL);
+
+ GPU_texture_anisotropic_filter(tex, true);
+
+ if (freebuf) {
+ MEM_freeN(data);
+ }
+
+ return tex;
+}
diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h
index ddf75aa3258..67f8aeb0a67 100644
--- a/source/blender/io/alembic/ABC_alembic.h
+++ b/source/blender/io/alembic/ABC_alembic.h
@@ -128,6 +128,16 @@ struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *han
struct Object *object,
const char *object_path);
+bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name);
+
+/* r_vertex_velocities should point to a preallocated array of num_vertices floats */
+int ABC_read_velocity_cache(struct CacheReader *reader,
+ const char *velocity_name,
+ float time,
+ float fps,
+ int num_vertices,
+ float *r_vertex_velocities);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.cc b/source/blender/io/alembic/intern/abc_axis_conversion.cc
index cebab1f2e41..396c8fdb28b 100644
--- a/source/blender/io/alembic/intern/abc_axis_conversion.cc
+++ b/source/blender/io/alembic/intern/abc_axis_conversion.cc
@@ -170,4 +170,4 @@ void create_transform_matrix(Object *obj,
} // namespace alembic
} // namespace io
-} // namespace blender \ No newline at end of file
+} // namespace blender
diff --git a/source/blender/io/alembic/intern/abc_axis_conversion.h b/source/blender/io/alembic/intern/abc_axis_conversion.h
index 9a19e9116be..645d9fc783b 100644
--- a/source/blender/io/alembic/intern/abc_axis_conversion.h
+++ b/source/blender/io/alembic/intern/abc_axis_conversion.h
@@ -100,4 +100,4 @@ void create_transform_matrix(Object *obj,
} // namespace alembic
} // namespace io
-} // namespace blender \ No newline at end of file
+} // namespace blender
diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc
index 7cde2d4fe73..eba7f64db02 100644
--- a/source/blender/io/alembic/intern/alembic_capi.cc
+++ b/source/blender/io/alembic/intern/alembic_capi.cc
@@ -22,6 +22,7 @@
#include <Alembic/AbcMaterial/IMaterial.h>
+#include "abc_axis_conversion.h"
#include "abc_reader_archive.h"
#include "abc_reader_camera.h"
#include "abc_reader_curves.h"
@@ -47,18 +48,13 @@
#include "BKE_lib_id.h"
#include "BKE_object.h"
#include "BKE_scene.h"
+#include "BKE_screen.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "ED_undo.h"
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
-#include "BKE_screen.h"
-#undef new
-
#include "BLI_compiler_compat.h"
#include "BLI_fileops.h"
#include "BLI_ghash.h"
@@ -70,7 +66,10 @@
#include "WM_api.h"
#include "WM_types.h"
+using Alembic::Abc::IV3fArrayProperty;
using Alembic::Abc::ObjectHeader;
+using Alembic::Abc::PropertyHeader;
+using Alembic::Abc::V3fArraySamplePtr;
using Alembic::AbcGeom::ICamera;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::IFaceSet;
@@ -79,9 +78,11 @@ using Alembic::AbcGeom::INuPatch;
using Alembic::AbcGeom::IObject;
using Alembic::AbcGeom::IPoints;
using Alembic::AbcGeom::IPolyMesh;
+using Alembic::AbcGeom::IPolyMeshSchema;
using Alembic::AbcGeom::ISampleSelector;
using Alembic::AbcGeom::ISubD;
using Alembic::AbcGeom::IXform;
+using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::MetaData;
using Alembic::AbcMaterial::IMaterial;
@@ -859,3 +860,136 @@ CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle,
return reinterpret_cast<CacheReader *>(abc_reader);
}
+
+/* ************************************************************************** */
+
+static const PropertyHeader *get_property_header(const IPolyMeshSchema &schema, const char *name)
+{
+ const PropertyHeader *prop_header = schema.getPropertyHeader(name);
+
+ if (prop_header) {
+ return prop_header;
+ }
+
+ ICompoundProperty prop = schema.getArbGeomParams();
+
+ if (!has_property(prop, name)) {
+ return nullptr;
+ }
+
+ return prop.getPropertyHeader(name);
+}
+
+bool ABC_has_vec3_array_property_named(struct CacheReader *reader, const char *name)
+{
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+
+ if (!abc_reader) {
+ return false;
+ }
+
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ return false;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+
+ if (!IPolyMesh::matches(header)) {
+ return false;
+ }
+
+ IPolyMesh mesh(iobject, kWrapExisting);
+ IPolyMeshSchema schema = mesh.getSchema();
+
+ const PropertyHeader *prop_header = get_property_header(schema, name);
+
+ if (!prop_header) {
+ return false;
+ }
+
+ return IV3fArrayProperty::matches(prop_header->getMetaData());
+}
+
+static V3fArraySamplePtr get_velocity_prop(const IPolyMeshSchema &schema,
+ const ISampleSelector &iss,
+ const std::string &name)
+{
+ const PropertyHeader *prop_header = schema.getPropertyHeader(name);
+
+ if (prop_header) {
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(schema, name, 0);
+ return velocity_prop.getValue(iss);
+ }
+
+ ICompoundProperty prop = schema.getArbGeomParams();
+
+ if (!has_property(prop, name)) {
+ return V3fArraySamplePtr();
+ }
+
+ const IV3fArrayProperty &velocity_prop = IV3fArrayProperty(prop, name, 0);
+
+ if (velocity_prop) {
+ return velocity_prop.getValue(iss);
+ }
+
+ return V3fArraySamplePtr();
+}
+
+int ABC_read_velocity_cache(CacheReader *reader,
+ const char *velocity_name,
+ const float time,
+ float velocity_scale,
+ int num_vertices,
+ float *r_vertex_velocities)
+{
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+
+ if (!abc_reader) {
+ return -1;
+ }
+
+ IObject iobject = abc_reader->iobject();
+
+ if (!iobject.valid()) {
+ return -1;
+ }
+
+ const ObjectHeader &header = iobject.getHeader();
+
+ if (!IPolyMesh::matches(header)) {
+ return -1;
+ }
+
+ IPolyMesh mesh(iobject, kWrapExisting);
+ IPolyMeshSchema schema = mesh.getSchema();
+ ISampleSelector sample_sel(time);
+ const IPolyMeshSchema::Sample sample = schema.getValue(sample_sel);
+
+ V3fArraySamplePtr velocities = get_velocity_prop(schema, sample_sel, velocity_name);
+
+ if (!velocities) {
+ return -1;
+ }
+
+ float vel[3];
+
+ int num_velocity_vectors = static_cast<int>(velocities->size());
+
+ if (num_velocity_vectors != num_vertices) {
+ return -1;
+ }
+
+ for (size_t i = 0; i < velocities->size(); ++i) {
+ const Imath::V3f &vel_in = (*velocities)[i];
+ copy_zup_from_yup(vel, vel_in.getValue());
+
+ mul_v3_fl(vel, velocity_scale);
+
+ copy_v3_v3(r_vertex_velocities + i * 3, vel);
+ }
+
+ return num_vertices;
+}
diff --git a/source/blender/io/avi/intern/avi.c b/source/blender/io/avi/intern/avi.c
index e829a15deba..0ab51b7a084 100644
--- a/source/blender/io/avi/intern/avi.c
+++ b/source/blender/io/avi/intern/avi.c
@@ -116,9 +116,8 @@ int AVI_get_stream(AviMovie *movie, int avist_type, int stream_num)
if (stream_num == 0) {
return cur_stream;
}
- else {
- stream_num--;
- }
+
+ stream_num--;
}
}
@@ -572,9 +571,8 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
if (GET_FCC(movie->fp) == FCC("movi")) {
break;
}
- else {
- BLI_fseek(movie->fp, size - 4, SEEK_CUR);
- }
+
+ BLI_fseek(movie->fp, size - 4, SEEK_CUR);
}
else {
BLI_fseek(movie->fp, size, SEEK_CUR);
diff --git a/source/blender/io/avi/intern/avi_rgb.c b/source/blender/io/avi/intern/avi_rgb.c
index 44542af96ae..8af728f0737 100644
--- a/source/blender/io/avi/intern/avi_rgb.c
+++ b/source/blender/io/avi/intern/avi_rgb.c
@@ -96,35 +96,34 @@ void *avi_converter_from_avi_rgb(AviMovie *movie,
return buf;
}
- else {
- buf = imb_alloc_pixels(
- movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
-
- if (buf) {
- size_t rowstride = movie->header->Width * 3;
- BLI_assert(bits != 16);
- if (movie->header->Width % 2) {
- rowstride++;
- }
- for (size_t y = 0; y < movie->header->Height; y++) {
- memcpy(&buf[y * movie->header->Width * 3],
- &buffer[((movie->header->Height - 1) - y) * rowstride],
- movie->header->Width * 3);
- }
+ buf = imb_alloc_pixels(
+ movie->header->Height, movie->header->Width, 3, sizeof(unsigned char), "fromavirgbbuf");
- for (size_t y = 0; y < (size_t)movie->header->Height * (size_t)movie->header->Width * 3;
- y += 3) {
- int i = buf[y];
- buf[y] = buf[y + 2];
- buf[y + 2] = i;
- }
+ if (buf) {
+ size_t rowstride = movie->header->Width * 3;
+ BLI_assert(bits != 16);
+ if (movie->header->Width % 2) {
+ rowstride++;
}
- MEM_freeN(buffer);
+ for (size_t y = 0; y < movie->header->Height; y++) {
+ memcpy(&buf[y * movie->header->Width * 3],
+ &buffer[((movie->header->Height - 1) - y) * rowstride],
+ movie->header->Width * 3);
+ }
- return buf;
+ for (size_t y = 0; y < (size_t)movie->header->Height * (size_t)movie->header->Width * 3;
+ y += 3) {
+ int i = buf[y];
+ buf[y] = buf[y + 2];
+ buf[y + 2] = i;
+ }
}
+
+ MEM_freeN(buffer);
+
+ return buf;
}
void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, size_t *size)
diff --git a/source/blender/io/collada/AnimationExporter.cpp b/source/blender/io/collada/AnimationExporter.cpp
index c25b4ea543b..a4302a680a3 100644
--- a/source/blender/io/collada/AnimationExporter.cpp
+++ b/source/blender/io/collada/AnimationExporter.cpp
@@ -230,7 +230,7 @@ void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler &
std::string name = encode_xml(id_name(ob));
std::string action_name = (action == NULL) ? name + "-action" : id_name(action);
std::string channel_type = "transform";
- std::string axis = "";
+ std::string axis;
std::string id = bc_get_action_id(action_name, name, channel_type, axis);
std::string target = translate_id(name) + '/' + channel_type;
@@ -395,15 +395,15 @@ bool AnimationExporter::is_bone_deform_group(Bone *bone)
return true;
}
/* Check child bones */
- else {
- for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
- /* loop through all the children until deform bone is found, and then return */
- is_def = is_bone_deform_group(child);
- if (is_def) {
- return true;
- }
+
+ for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) {
+ /* loop through all the children until deform bone is found, and then return */
+ is_def = is_bone_deform_group(child);
+ if (is_def) {
+ return true;
}
}
+
/* no deform bone found in children also */
return false;
}
@@ -840,12 +840,11 @@ std::string AnimationExporter::get_collada_sid(const BCAnimationCurve &curve,
if (is_angle) {
return tm_name + std::string(axis_name) + ".ANGLE";
}
- else if (!axis_name.empty()) {
+ if (!axis_name.empty()) {
return tm_name + "." + std::string(axis_name);
}
- else {
- return tm_name;
- }
+
+ return tm_name;
}
return tm_name;
diff --git a/source/blender/io/collada/AnimationImporter.cpp b/source/blender/io/collada/AnimationImporter.cpp
index b53aa95a11f..1dada68293e 100644
--- a/source/blender/io/collada/AnimationImporter.cpp
+++ b/source/blender/io/collada/AnimationImporter.cpp
@@ -717,37 +717,36 @@ void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listi
if (animlist_map.find(listid) == animlist_map.end()) {
return;
}
- else {
- /* anim_type has animations */
- const COLLADAFW::AnimationList *animlist = animlist_map[listid];
- const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
- /* all the curves belonging to the current binding */
- std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
- animcurves = curve_map[bindings[j].animation];
-
- BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
- modify_fcurve(&animcurves, rna_path, 0);
- std::vector<FCurve *>::iterator iter;
- /* Add the curves of the current animation to the object */
- for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
- FCurve *fcu = *iter;
- /* All anim_types whose values are to be converted from Degree to Radians can be ORed here
+
+ /* anim_type has animations */
+ const COLLADAFW::AnimationList *animlist = animlist_map[listid];
+ const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
+ /* all the curves belonging to the current binding */
+ std::vector<FCurve *> animcurves;
+ for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ animcurves = curve_map[bindings[j].animation];
+
+ BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
+ modify_fcurve(&animcurves, rna_path, 0);
+ std::vector<FCurve *>::iterator iter;
+ /* Add the curves of the current animation to the object */
+ for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
+ FCurve *fcu = *iter;
+ /* All anim_types whose values are to be converted from Degree to Radians can be ORed here
+ */
+ if (STREQ("spot_size", anim_type)) {
+ /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10
+ * Reason: old blender versions stored spot_size in radians (was a bug)
*/
- if (STREQ("spot_size", anim_type)) {
- /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10
- * Reason: old blender versions stored spot_size in radians (was a bug)
- */
- if (this->import_from_version.empty() ||
- BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) {
- fcurve_deg_to_rad(fcu);
- }
+ if (this->import_from_version.empty() ||
+ BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) {
+ fcurve_deg_to_rad(fcu);
}
- /** XXX What About animtype "rotation" ? */
-
- BLI_addtail(AnimCurves, fcu);
- fcurve_is_used(fcu);
}
+ /** XXX What About animtype "rotation" ? */
+
+ BLI_addtail(AnimCurves, fcu);
+ fcurve_is_used(fcu);
}
}
}
@@ -780,35 +779,34 @@ void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid
if (animlist_map.find(listid) == animlist_map.end()) {
return;
}
- else {
- /* anim_type has animations */
- const COLLADAFW::AnimationList *animlist = animlist_map[listid];
- const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
- /* all the curves belonging to the current binding */
- std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
- animcurves = curve_map[bindings[j].animation];
- BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
+ /* anim_type has animations */
+ const COLLADAFW::AnimationList *animlist = animlist_map[listid];
+ const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings();
+ /* all the curves belonging to the current binding */
+ std::vector<FCurve *> animcurves;
+ for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ animcurves = curve_map[bindings[j].animation];
- modify_fcurve(&animcurves, rna_path, 0);
- std::vector<FCurve *>::iterator iter;
- /* Add the curves of the current animation to the object */
- for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
- FCurve *fcu = *iter;
+ BLI_strncpy(rna_path, anim_type, sizeof(rna_path));
- for (unsigned int i = 0; i < fcu->totvert; i++) {
- fcu->bezt[i].vec[0][1] = convert_to_focal_length(
- fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
- fcu->bezt[i].vec[1][1] = convert_to_focal_length(
- fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x);
- fcu->bezt[i].vec[2][1] = convert_to_focal_length(
- fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x);
- }
+ modify_fcurve(&animcurves, rna_path, 0);
+ std::vector<FCurve *>::iterator iter;
+ /* Add the curves of the current animation to the object */
+ for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
+ FCurve *fcu = *iter;
- BLI_addtail(AnimCurves, fcu);
- fcurve_is_used(fcu);
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ fcu->bezt[i].vec[0][1] = convert_to_focal_length(
+ fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x);
+ fcu->bezt[i].vec[1][1] = convert_to_focal_length(
+ fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x);
+ fcu->bezt[i].vec[2][1] = convert_to_focal_length(
+ fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x);
}
+
+ BLI_addtail(AnimCurves, fcu);
+ fcurve_is_used(fcu);
}
}
}
@@ -1077,35 +1075,34 @@ void AnimationImporter::translate_Animations(
if (animlist_map.find(listid) == animlist_map.end()) {
continue;
}
- else {
- /* transformation has animations */
- const COLLADAFW::AnimationList *animlist = animlist_map[listid];
- const COLLADAFW::AnimationList::AnimationBindings &bindings =
- animlist->getAnimationBindings();
- /* all the curves belonging to the current binding */
- std::vector<FCurve *> animcurves;
- for (unsigned int j = 0; j < bindings.getCount(); j++) {
- animcurves = curve_map[bindings[j].animation];
- if (is_matrix) {
- apply_matrix_curves(ob, animcurves, root, node, transform);
- }
- else {
- /* calculate rnapaths and array index of fcurves according to transformation and
- * animation class */
- Assign_transform_animations(
- transform, &bindings[j], &animcurves, is_joint, joint_path);
-
- std::vector<FCurve *>::iterator iter;
- /* Add the curves of the current animation to the object */
- for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
- FCurve *fcu = *iter;
-
- BLI_addtail(AnimCurves, fcu);
- fcurve_is_used(fcu);
- }
+
+ /* transformation has animations */
+ const COLLADAFW::AnimationList *animlist = animlist_map[listid];
+ const COLLADAFW::AnimationList::AnimationBindings &bindings =
+ animlist->getAnimationBindings();
+ /* all the curves belonging to the current binding */
+ std::vector<FCurve *> animcurves;
+ for (unsigned int j = 0; j < bindings.getCount(); j++) {
+ animcurves = curve_map[bindings[j].animation];
+ if (is_matrix) {
+ apply_matrix_curves(ob, animcurves, root, node, transform);
+ }
+ else {
+ /* calculate rnapaths and array index of fcurves according to transformation and
+ * animation class */
+ Assign_transform_animations(transform, &bindings[j], &animcurves, is_joint, joint_path);
+
+ std::vector<FCurve *>::iterator iter;
+ /* Add the curves of the current animation to the object */
+ for (iter = animcurves.begin(); iter != animcurves.end(); iter++) {
+ FCurve *fcu = *iter;
+
+ BLI_addtail(AnimCurves, fcu);
+ fcurve_is_used(fcu);
}
}
}
+
if (is_rotation && !(is_joint || is_matrix)) {
ob->rotmode = ROT_MODE_EUL;
}
@@ -1423,10 +1420,9 @@ AnimationImporter::AnimMix *AnimationImporter::get_animation_type(
if (animlist_map.find(listid) == animlist_map.end()) {
continue;
}
- else {
- types->transform = types->transform | BC_NODE_TRANSFORM;
- break;
- }
+
+ types->transform = types->transform | BC_NODE_TRANSFORM;
+ break;
}
const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights();
@@ -1995,7 +1991,7 @@ bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm,
return true;
}
- else if (is_scale || is_translate) {
+ if (is_scale || is_translate) {
bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ;
if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) {
diff --git a/source/blender/io/collada/BCAnimationCurve.cpp b/source/blender/io/collada/BCAnimationCurve.cpp
index 61dded368b5..5fdbb65fb6e 100644
--- a/source/blender/io/collada/BCAnimationCurve.cpp
+++ b/source/blender/io/collada/BCAnimationCurve.cpp
@@ -559,9 +559,8 @@ inline bool operator<(const BCAnimationCurve &lhs, const BCAnimationCurve &rhs)
const int rha = rhs.get_channel_index();
return lha < rha;
}
- else {
- return lhtgt < rhtgt;
- }
+
+ return lhtgt < rhtgt;
}
BCCurveKey::BCCurveKey()
diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp
index 0f84db79c28..83c8a805076 100644
--- a/source/blender/io/collada/DocumentImporter.cpp
+++ b/source/blender/io/collada/DocumentImporter.cpp
@@ -1254,9 +1254,6 @@ bool DocumentImporter::is_armature(COLLADAFW::Node *node)
if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) {
return true;
}
- else {
- continue;
- }
}
/* no child is JOINT */
diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp
index f123e8ea31f..b3fa9ba1251 100644
--- a/source/blender/io/collada/collada_internal.cpp
+++ b/source/blender/io/collada/collada_internal.cpp
@@ -277,7 +277,7 @@ std::string encode_xml(std::string xml)
{'<', "&lt;"}, {'>', "&gt;"}, {'"', "&quot;"}, {'\'', "&apos;"}, {'&', "&amp;"}};
std::map<char, std::string>::const_iterator it;
- std::string encoded_xml = "";
+ std::string encoded_xml;
for (unsigned int i = 0; i < xml.size(); i++) {
char c = xml.at(i);
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index 2c54a49198a..2493b3a386b 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -88,9 +88,8 @@ float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned in
if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) {
return array.getFloatValues()->getData()[index];
}
- else {
- return array.getDoubleValues()->getData()[index];
- }
+
+ return array.getDoubleValues()->getData()[index];
}
/* copied from /editors/object/object_relations.c */
@@ -330,9 +329,8 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
}
return (aBone == root);
}
- else {
- return !(aBone->parent);
- }
+
+ return !(aBone->parent);
}
int bc_get_active_UVLayer(Object *ob)
@@ -672,8 +670,7 @@ void BoneExtended::set_bone_layers(std::string layerString, std::vector<std::str
std::string BoneExtended::get_bone_layers(int bitfield)
{
- std::string result = "";
- std::string sep = "";
+ std::string sep;
int bit = 1u;
std::ostringstream ss;
@@ -1323,9 +1320,8 @@ COLLADASW::ColorOrTexture bc_get_base_color(Material *ma)
if (ma->use_nodes && shader) {
return bc_get_cot_from_shader(shader, "Base Color", default_color, false);
}
- else {
- return bc_get_cot(default_color);
- }
+
+ return bc_get_cot(default_color);
}
COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
@@ -1335,9 +1331,8 @@ COLLADASW::ColorOrTexture bc_get_emission(Material *ma)
if (ma->use_nodes && shader) {
return bc_get_cot_from_shader(shader, "Emission", default_color);
}
- else {
- return bc_get_cot(default_color); /* default black */
- }
+
+ return bc_get_cot(default_color); /* default black */
}
COLLADASW::ColorOrTexture bc_get_ambient(Material *ma)
@@ -1420,9 +1415,8 @@ COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader,
float *col = dcol->value;
return bc_get_cot(col, with_alpha);
}
- else {
- return bc_get_cot(default_color, with_alpha);
- }
+
+ return bc_get_cot(default_color, with_alpha);
}
bNode *bc_get_master_shader(Material *ma)
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 10a7dbcd811..c79ae68678f 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -66,7 +66,9 @@ typedef struct BrushGpencilSettings {
short draw_smoothlvl;
/** Number of times to subdivide new strokes. */
short draw_subdivide;
- char _pad[4];
+ /** Layers used for fill. */
+ short fill_layer_mode;
+ char _pad[2];
/** Factor for transparency. */
float fill_threshold;
@@ -117,7 +119,8 @@ typedef struct BrushGpencilSettings {
int sculpt_mode_flag;
/** Preset type (used to reset brushes - internal). */
short preset_type;
- char _pad3[2];
+ /** Brush preselected mode (Active/Material/Vertexcolor). */
+ short brush_draw_mode;
/** Randomness for Hue. */
float random_hue;
@@ -250,6 +253,16 @@ typedef enum eGP_FillDrawModes {
GP_FILL_DMODE_CONTROL = 2,
} eGP_FillDrawModes;
+/* BrushGpencilSettings->fill_layer_mode */
+typedef enum eGP_FillLayerModes {
+ GP_FILL_GPLMODE_VISIBLE = 0,
+ GP_FILL_GPLMODE_ACTIVE = 1,
+ GP_FILL_GPLMODE_ALL_ABOVE = 2,
+ GP_FILL_GPLMODE_ALL_BELOW = 3,
+ GP_FILL_GPLMODE_ABOVE = 4,
+ GP_FILL_GPLMODE_BELOW = 5,
+} eGP_FillLayerModes;
+
/* BrushGpencilSettings->gp_eraser_mode */
typedef enum eGP_BrushEraserMode {
GP_BRUSH_ERASER_SOFT = 0,
@@ -257,6 +270,13 @@ typedef enum eGP_BrushEraserMode {
GP_BRUSH_ERASER_STROKE = 2,
} eGP_BrushEraserMode;
+/* BrushGpencilSettings->brush_draw_mode */
+typedef enum eGP_BrushMode {
+ GP_BRUSH_MODE_ACTIVE = 0,
+ GP_BRUSH_MODE_MATERIAL = 1,
+ GP_BRUSH_MODE_VERTEXCOLOR = 2,
+} eGP_BrushMode;
+
/* BrushGpencilSettings default brush icons */
typedef enum eGP_BrushIcons {
GP_BRUSH_ICON_PENCIL = 1,
@@ -330,6 +350,11 @@ typedef enum eBrushClothForceFalloffType {
BRUSH_CLOTH_FORCE_FALLOFF_PLANE = 1,
} eBrushClothForceFalloffType;
+typedef enum eBrushClothSimulationAreaType {
+ BRUSH_CLOTH_SIMULATION_AREA_LOCAL = 0,
+ BRUSH_CLOTH_SIMULATION_AREA_GLOBAL = 1,
+} eBrushClothSimulationAreaType;
+
typedef enum eBrushPoseDeformType {
BRUSH_POSE_DEFORM_ROTATE_TWIST = 0,
BRUSH_POSE_DEFORM_SCALE_TRASLATE = 1,
@@ -499,7 +524,7 @@ typedef struct Brush {
/** Source for fill tool color gradient application. */
char gradient_fill_mode;
- char _pad0[1];
+ char _pad0[5];
/** Projection shape (sphere, circle). */
char falloff_shape;
@@ -525,7 +550,7 @@ typedef struct Brush {
char gpencil_sculpt_tool;
/** Active grease pencil weight tool. */
char gpencil_weight_tool;
- char _pad1[6];
+ char _pad1[2];
float autosmooth_factor;
@@ -564,6 +589,7 @@ typedef struct Brush {
/* cloth */
int cloth_deform_type;
int cloth_force_falloff_type;
+ int cloth_simulation_area_type;
float cloth_mass;
float cloth_damping;
@@ -571,6 +597,8 @@ typedef struct Brush {
float cloth_sim_limit;
float cloth_sim_falloff;
+ float cloth_constraint_softbody_strength;
+
/* smooth */
int smooth_deform_type;
float surface_smooth_shape_preservation;
@@ -715,6 +743,9 @@ typedef enum eBrushFlags2 {
BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW = (1 << 1),
BRUSH_POSE_IK_ANCHORED = (1 << 2),
BRUSH_USE_CONNECTED_ONLY = (1 << 3),
+ BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY = (1 << 4),
+ BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5),
+ BRUSH_CLOTH_USE_COLLISION = (1 << 6),
} eBrushFlags2;
typedef enum {
diff --git a/source/blender/makesdna/DNA_cachefile_types.h b/source/blender/makesdna/DNA_cachefile_types.h
index 581248ed52b..04c99c6c4b1 100644
--- a/source/blender/makesdna/DNA_cachefile_types.h
+++ b/source/blender/makesdna/DNA_cachefile_types.h
@@ -52,6 +52,13 @@ typedef struct AlembicObjectPath {
char path[4096];
} AlembicObjectPath;
+/* CacheFile::velocity_unit
+ * Determines what temporal unit is used to interpret velocity vectors for motion blur effects. */
+enum {
+ CACHEFILE_VELOCITY_UNIT_FRAME,
+ CACHEFILE_VELOCITY_UNIT_SECOND,
+};
+
typedef struct CacheFile {
ID id;
struct AnimData *adt;
@@ -77,7 +84,11 @@ typedef struct CacheFile {
short flag;
short draw_flag; /* UNUSED */
- char _pad[4];
+ char _pad[3];
+
+ char velocity_unit;
+ /* Name of the velocity property in the Alembic file. */
+ char velocity_name[64];
/* Runtime */
struct AbcArchiveHandle *handle;
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index c442e160bad..2ae9ba13177 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -273,9 +273,12 @@ typedef struct Curve {
int selstart, selend;
/* text data */
- /** Number of characters (strinfo). */
- int len_wchar;
- /** Number of bytes (str - utf8). */
+ /**
+ * Number of characters (unicode code-points)
+ * This is the length of #Curve.strinfo and the result of `BLI_strlen_utf8(cu->str)`.
+ */
+ int len_char32;
+ /** Number of bytes: `strlen(Curve.str)`. */
int len;
char *str;
struct EditFont *editfont;
diff --git a/source/blender/makesdna/DNA_curveprofile_types.h b/source/blender/makesdna/DNA_curveprofile_types.h
index b45eb832232..5b425741df2 100644
--- a/source/blender/makesdna/DNA_curveprofile_types.h
+++ b/source/blender/makesdna/DNA_curveprofile_types.h
@@ -30,7 +30,7 @@
/** Number of table points per control point. */
#define PROF_RESOL 16
/** Dynamic size of widget's high resolution table. Input should be profile->totpoint. */
-#define PROF_N_TABLE(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1)
+#define PROF_TABLE_LEN(n_pts) min_ii(PROF_TABLE_MAX, (((n_pts - 1)) * PROF_RESOL) + 1)
/**
* Each control point that makes up the profile.
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 17f3fe24fbc..749bc55fcb9 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -116,13 +116,13 @@ typedef struct ImageTile {
#define IMA_NEED_FRAME_RECALC (1 << 3)
#define IMA_SHOW_STEREO (1 << 4)
-enum {
- TEXTARGET_TEXTURE_2D = 0,
- TEXTARGET_TEXTURE_CUBE_MAP = 1,
- TEXTARGET_TEXTURE_2D_ARRAY = 2,
- TEXTARGET_TEXTURE_TILE_MAPPING = 3,
- TEXTARGET_COUNT = 4,
-};
+/* Used to get the correct gpu texture from an Image datablock. */
+typedef enum eGPUTextureTarget {
+ TEXTARGET_2D = 0,
+ TEXTARGET_2D_ARRAY,
+ TEXTARGET_TILE_MAPPING,
+ TEXTARGET_COUNT,
+} eGPUTextureTarget;
typedef struct Image {
ID id;
@@ -132,8 +132,8 @@ typedef struct Image {
/** Not written in file. */
struct MovieCache *cache;
- /** Not written in file 4 = TEXTARGET_COUNT, 2 = stereo eyes. */
- struct GPUTexture *gputexture[4][2];
+ /** Not written in file 3 = TEXTARGET_COUNT, 2 = stereo eyes. */
+ struct GPUTexture *gputexture[3][2];
/* sources from: */
ListBase anims;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 93434e64df1..b01b3f42e6a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1276,7 +1276,11 @@ typedef struct OceanModifierData {
struct Ocean *ocean;
struct OceanCache *oceancache;
+ /** Render resolution. */
int resolution;
+ /** Viewport resolution for the non-render case. */
+ int viewport_resolution;
+
int spatial_size;
float wind_velocity;
@@ -1293,8 +1297,6 @@ typedef struct OceanModifierData {
float foam_coverage;
float time;
- char _pad1[4];
-
/* Spectrum being used. */
int spectrum;
@@ -2051,6 +2053,10 @@ enum {
MOD_NORMALEDIT_MIX_MUL = 3,
};
+typedef struct MeshCacheVertexVelocity {
+ float vel[3];
+} MeshCacheVertexVelocity;
+
typedef struct MeshSeqCacheModifierData {
ModifierData modifier;
@@ -2059,11 +2065,31 @@ typedef struct MeshSeqCacheModifierData {
char object_path[1024];
char read_flag;
- char _pad[7];
+ char _pad[3];
+
+ float velocity_scale;
/* Runtime. */
struct CacheReader *reader;
char reader_object_path[1024];
+
+ /* Vertex velocities read from the cache. The velocities are not automatically read during
+ * modifier execution, and therefore have to manually be read when needed. This is only used
+ * through the RNA for now. */
+ struct MeshCacheVertexVelocity *vertex_velocities;
+
+ /* The number of vertices of the Alembic mesh, set when the modifier is executed. */
+ int num_vertices;
+
+ /* Time (in frames or seconds) between two velocity samples. Automatically computed to
+ * scale the velocity vectors at render time for generating proper motion blur data. */
+ float velocity_delta;
+
+ /* Caches the scene time (in seconds) used to lookup data in the Alembic archive when the
+ * modifier was last executed. Used to access Alembic samples through the RNA. */
+ float last_lookup_time;
+
+ int _pad1;
} MeshSeqCacheModifierData;
/* MeshSeqCacheModifierData.read_flag */
diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h
index 123ff5bfb7e..2b1fd546450 100644
--- a/source/blender/makesdna/DNA_movieclip_types.h
+++ b/source/blender/makesdna/DNA_movieclip_types.h
@@ -63,8 +63,8 @@ typedef struct MovieClipProxy {
typedef struct MovieClip_RuntimeGPUTexture {
void *next, *prev;
MovieClipUser user;
- /** Not written in file 4 = TEXTARGET_COUNT. */
- struct GPUTexture *gputexture[4];
+ /** Not written in file 3 = TEXTARGET_COUNT. */
+ struct GPUTexture *gputexture[3];
} MovieClip_RuntimeGPUTexture;
typedef struct MovieClip_Runtime {
diff --git a/source/blender/makesdna/DNA_rigidbody_types.h b/source/blender/makesdna/DNA_rigidbody_types.h
index 3a4925217ff..02a4a158d8c 100644
--- a/source/blender/makesdna/DNA_rigidbody_types.h
+++ b/source/blender/makesdna/DNA_rigidbody_types.h
@@ -213,7 +213,7 @@ typedef enum eRigidBody_Shape {
RB_SHAPE_TRIMESH = 6,
/* concave mesh approximated using primitives */
- // RB_SHAPE_COMPOUND,
+ RB_SHAPE_COMPOUND = 7,
} eRigidBody_Shape;
typedef enum eRigidBody_MeshSource {
diff --git a/source/blender/makesdna/DNA_simulation_types.h b/source/blender/makesdna/DNA_simulation_types.h
index de4c9522334..8cc2db99332 100644
--- a/source/blender/makesdna/DNA_simulation_types.h
+++ b/source/blender/makesdna/DNA_simulation_types.h
@@ -29,16 +29,21 @@ typedef struct Simulation {
struct bNodeTree *nodetree;
- int flag;
+ uint32_t flag;
+
+ /** This is the frame in scene time, that the states correspond to. */
float current_frame;
+
+ /** Time since the start of the simulation in simulation time (which might differ from scene
+ * time). */
float current_simulation_time;
char _pad[4];
/** List containing SimulationState objects. */
struct ListBase states;
- /** List containing PersistentDataHandleItem objects. */
- struct ListBase persistent_data_handles;
+ /** List containing SimulationDependency objects. */
+ struct ListBase dependencies;
} Simulation;
typedef struct SimulationState {
@@ -53,8 +58,8 @@ typedef struct ParticleSimulationState {
SimulationState head;
/** Contains the state of the particles at time Simulation->current_frame. */
- int tot_particles;
- int next_particle_id;
+ int32_t tot_particles;
+ int32_t next_particle_id;
struct CustomData attributes;
} ParticleSimulationState;
@@ -65,19 +70,26 @@ typedef struct ParticleMeshEmitterSimulationState {
char _pad[4];
} ParticleMeshEmitterSimulationState;
-/** Stores a mapping between an integer handle and a corresponding ID data block. */
-typedef struct PersistentDataHandleItem {
- struct PersistentDataHandleItem *next;
- struct PersistentDataHandleItem *prev;
+/** Stores a reference to data that the simulation depends on. This is partially derived from the
+ * simulation node tree. */
+typedef struct SimulationDependency {
+ struct SimulationDependency *next;
+ struct SimulationDependency *prev;
struct ID *id;
- int handle;
- char _pad[4];
-} PersistentDataHandleItem;
+ int32_t handle;
+ uint32_t flag;
+} SimulationDependency;
/* Simulation.flag */
enum {
SIM_DS_EXPAND = (1 << 0),
};
+/* SimulationDependency.flag */
+enum {
+ SIM_DEPENDS_ON_TRANSFORM = (1 << 0),
+ SIM_DEPENDS_ON_GEOMETRY = (1 << 1),
+};
+
#define SIM_TYPE_NAME_PARTICLE_SIMULATION "Particle Simulation"
#define SIM_TYPE_NAME_PARTICLE_MESH_EMITTER "Particle Mesh Emitter"
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index a632d42fd8b..c2ed6c97d3d 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -732,7 +732,7 @@ typedef struct UserDef {
char _pad1[2];
int undomemory;
float gpu_viewport_quality DNA_DEPRECATED;
- short gp_manhattendist, gp_euclideandist, gp_eraser;
+ short gp_manhattandist, gp_euclideandist, gp_eraser;
/** #eGP_UserdefSettings. */
short gp_settings;
char _pad13[4];
diff --git a/source/blender/makesdna/DNA_view2d_types.h b/source/blender/makesdna/DNA_view2d_types.h
index d7a6386d12f..63038b6be2d 100644
--- a/source/blender/makesdna/DNA_view2d_types.h
+++ b/source/blender/makesdna/DNA_view2d_types.h
@@ -136,7 +136,7 @@ enum {
/* apply pixel offsets on y-axis when setting view matrices */
V2D_PIXELOFS_Y = (1 << 3),
/* view settings need to be set still... */
- V2D_IS_INITIALISED = (1 << 10),
+ V2D_IS_INIT = (1 << 10),
};
/* scroller flags for View2D (v2d->scroll) */
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 4a6d642bcb6..dd11fed021d 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -197,8 +197,8 @@ typedef struct wmWindowManager {
/* wmWindowManager.initialized */
enum {
- WM_WINDOW_IS_INITIALIZED = (1 << 0),
- WM_KEYCONFIG_IS_INITIALIZED = (1 << 1),
+ WM_WINDOW_IS_INIT = (1 << 0),
+ WM_KEYCONFIG_IS_INIT = (1 << 1),
};
/* wmWindowManager.outliner_sync_select_dirty */
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 3d95eba4aed..53ed010952e 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -356,141 +356,140 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
*r_error_message = "SDNA error in SDNA file";
return false;
}
- else {
- const char *cp;
- data++;
- /* Names array ('NAME') */
- if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
- data++;
+ const char *cp;
- sdna->names_len = *data;
- if (do_endian_swap) {
- BLI_endian_switch_int32(&sdna->names_len);
- }
- sdna->names_len_alloc = sdna->names_len;
+ data++;
+ /* Names array ('NAME') */
+ if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
+ data++;
- data++;
- sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames");
- }
- else {
- *r_error_message = "NAME error in SDNA file";
- return false;
+ sdna->names_len = *data;
+ if (do_endian_swap) {
+ BLI_endian_switch_int32(&sdna->names_len);
}
+ sdna->names_len_alloc = sdna->names_len;
- cp = (char *)data;
- for (int nr = 0; nr < sdna->names_len; nr++) {
- sdna->names[nr] = cp;
-
- /* "float gravity [3]" was parsed wrong giving both "gravity" and
- * "[3]" members. we rename "[3]", and later set the type of
- * "gravity" to "void" so the offsets work out correct */
- if (*cp == '[' && strcmp(cp, "[3]") == 0) {
- if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) {
- sdna->names[nr] = "gravity[3]";
- gravity_fix = nr;
- }
- }
- while (*cp) {
- cp++;
+ data++;
+ sdna->names = MEM_callocN(sizeof(void *) * sdna->names_len, "sdnanames");
+ }
+ else {
+ *r_error_message = "NAME error in SDNA file";
+ return false;
+ }
+
+ cp = (char *)data;
+ for (int nr = 0; nr < sdna->names_len; nr++) {
+ sdna->names[nr] = cp;
+
+ /* "float gravity [3]" was parsed wrong giving both "gravity" and
+ * "[3]" members. we rename "[3]", and later set the type of
+ * "gravity" to "void" so the offsets work out correct */
+ if (*cp == '[' && strcmp(cp, "[3]") == 0) {
+ if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) {
+ sdna->names[nr] = "gravity[3]";
+ gravity_fix = nr;
}
+ }
+ while (*cp) {
cp++;
}
+ cp++;
+ }
- cp = pad_up_4(cp);
-
- /* Type names array ('TYPE') */
- data = (int *)cp;
- if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
- data++;
+ cp = pad_up_4(cp);
- sdna->types_len = *data;
- if (do_endian_swap) {
- BLI_endian_switch_int32(&sdna->types_len);
- }
+ /* Type names array ('TYPE') */
+ data = (int *)cp;
+ if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
+ data++;
- data++;
- sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes");
- }
- else {
- *r_error_message = "TYPE error in SDNA file";
- return false;
+ sdna->types_len = *data;
+ if (do_endian_swap) {
+ BLI_endian_switch_int32(&sdna->types_len);
}
- cp = (char *)data;
- for (int nr = 0; nr < sdna->types_len; nr++) {
- /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */
- sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp);
- while (*cp) {
- cp++;
- }
+ data++;
+ sdna->types = MEM_callocN(sizeof(void *) * sdna->types_len, "sdnatypes");
+ }
+ else {
+ *r_error_message = "TYPE error in SDNA file";
+ return false;
+ }
+
+ cp = (char *)data;
+ for (int nr = 0; nr < sdna->types_len; nr++) {
+ /* WARNING! See: DNA_struct_rename_legacy_hack_static_from_alias docs. */
+ sdna->types[nr] = DNA_struct_rename_legacy_hack_static_from_alias(cp);
+ while (*cp) {
cp++;
}
+ cp++;
+ }
- cp = pad_up_4(cp);
-
- /* Type lengths array ('TLEN') */
- data = (int *)cp;
- if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
- data++;
- sp = (short *)data;
- sdna->types_size = sp;
+ cp = pad_up_4(cp);
- if (do_endian_swap) {
- BLI_endian_switch_int16_array(sp, sdna->types_len);
- }
+ /* Type lengths array ('TLEN') */
+ data = (int *)cp;
+ if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
+ data++;
+ sp = (short *)data;
+ sdna->types_size = sp;
- sp += sdna->types_len;
- }
- else {
- *r_error_message = "TLEN error in SDNA file";
- return false;
- }
- /* prevent BUS error */
- if (sdna->types_len & 1) {
- sp++;
+ if (do_endian_swap) {
+ BLI_endian_switch_int16_array(sp, sdna->types_len);
}
- /* Struct array ('STRC') */
- data = (int *)sp;
- if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
- data++;
+ sp += sdna->types_len;
+ }
+ else {
+ *r_error_message = "TLEN error in SDNA file";
+ return false;
+ }
+ /* prevent BUS error */
+ if (sdna->types_len & 1) {
+ sp++;
+ }
- sdna->structs_len = *data;
- if (do_endian_swap) {
- BLI_endian_switch_int32(&sdna->structs_len);
- }
+ /* Struct array ('STRC') */
+ data = (int *)sp;
+ if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
+ data++;
- data++;
- sdna->structs = MEM_callocN(sizeof(void *) * sdna->structs_len, "sdnastrcs");
- }
- else {
- *r_error_message = "STRC error in SDNA file";
- return false;
+ sdna->structs_len = *data;
+ if (do_endian_swap) {
+ BLI_endian_switch_int32(&sdna->structs_len);
}
- sp = (short *)data;
- for (int nr = 0; nr < sdna->structs_len; nr++) {
- sdna->structs[nr] = sp;
+ data++;
+ sdna->structs = MEM_callocN(sizeof(void *) * sdna->structs_len, "sdnastrcs");
+ }
+ else {
+ *r_error_message = "STRC error in SDNA file";
+ return false;
+ }
+
+ sp = (short *)data;
+ for (int nr = 0; nr < sdna->structs_len; nr++) {
+ sdna->structs[nr] = sp;
- if (do_endian_swap) {
- short a;
+ if (do_endian_swap) {
+ short a;
+ BLI_endian_switch_int16(&sp[0]);
+ BLI_endian_switch_int16(&sp[1]);
+
+ a = sp[1];
+ sp += 2;
+ while (a--) {
BLI_endian_switch_int16(&sp[0]);
BLI_endian_switch_int16(&sp[1]);
-
- a = sp[1];
sp += 2;
- while (a--) {
- BLI_endian_switch_int16(&sp[0]);
- BLI_endian_switch_int16(&sp[1]);
- sp += 2;
- }
- }
- else {
- sp += 2 * sp[1] + 2;
}
}
+ else {
+ sp += 2 * sp[1] + 2;
+ }
}
{
@@ -578,16 +577,15 @@ SDNA *DNA_sdna_from_data(const void *data,
if (init_structDNA(sdna, do_endian_swap, &error_message)) {
return sdna;
}
+
+ if (r_error_message == NULL) {
+ fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message);
+ }
else {
- if (r_error_message == NULL) {
- fprintf(stderr, "Error decoding blend file SDNA: %s\n", error_message);
- }
- else {
- *r_error_message = error_message;
- }
- DNA_sdna_free(sdna);
- return NULL;
+ *r_error_message = error_message;
}
+ DNA_sdna_free(sdna);
+ return NULL;
}
/**
@@ -764,34 +762,33 @@ static eSDNA_Type sdna_type_nr(const char *dna_type)
if (STR_ELEM(dna_type, "char", "const char")) {
return SDNA_TYPE_CHAR;
}
- else if (STR_ELEM(dna_type, "uchar", "unsigned char")) {
+ if (STR_ELEM(dna_type, "uchar", "unsigned char")) {
return SDNA_TYPE_UCHAR;
}
- else if (STR_ELEM(dna_type, "short")) {
+ if (STR_ELEM(dna_type, "short")) {
return SDNA_TYPE_SHORT;
}
- else if (STR_ELEM(dna_type, "ushort", "unsigned short")) {
+ if (STR_ELEM(dna_type, "ushort", "unsigned short")) {
return SDNA_TYPE_USHORT;
}
- else if (STR_ELEM(dna_type, "int")) {
+ if (STR_ELEM(dna_type, "int")) {
return SDNA_TYPE_INT;
}
- else if (STR_ELEM(dna_type, "float")) {
+ if (STR_ELEM(dna_type, "float")) {
return SDNA_TYPE_FLOAT;
}
- else if (STR_ELEM(dna_type, "double")) {
+ if (STR_ELEM(dna_type, "double")) {
return SDNA_TYPE_DOUBLE;
}
- else if (STR_ELEM(dna_type, "int64_t")) {
+ if (STR_ELEM(dna_type, "int64_t")) {
return SDNA_TYPE_INT64;
}
- else if (STR_ELEM(dna_type, "uint64_t")) {
+ if (STR_ELEM(dna_type, "uint64_t")) {
return SDNA_TYPE_UINT64;
}
/* invalid! */
- else {
- return -1;
- }
+
+ return -1;
}
/**
@@ -1150,7 +1147,7 @@ static void reconstruct_elem(const SDNA *newsdna,
return;
}
- else if (countpos != 0) { /* name is an array */
+ if (countpos != 0) { /* name is an array */
if (oname[countpos] == '[' && strncmp(name, oname, countpos) == 0) { /* basis equal */
const int new_name_array_len = newsdna->names_array_len[new_name_nr];
diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h
index f2cf72843bd..a73fc747f84 100644
--- a/source/blender/makesdna/intern/dna_rename_defs.h
+++ b/source/blender/makesdna/intern/dna_rename_defs.h
@@ -67,6 +67,7 @@ DNA_STRUCT_RENAME_ELEM(Bone, scaleOut, scale_out_x)
DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_f, hardeness)
DNA_STRUCT_RENAME_ELEM(BrushGpencilSettings, gradient_s, aspect_ratio)
DNA_STRUCT_RENAME_ELEM(Camera, YF_dofdist, dof_distance)
+DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32)
DNA_STRUCT_RENAME_ELEM(Camera, clipend, clip_end)
DNA_STRUCT_RENAME_ELEM(Camera, clipsta, clip_start)
DNA_STRUCT_RENAME_ELEM(Collection, dupli_ofs, instance_offset)
@@ -90,6 +91,7 @@ DNA_STRUCT_RENAME_ELEM(ParticleSettings, dupliweights, instance_weights)
DNA_STRUCT_RENAME_ELEM(Text, name, filepath)
DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background)
DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type)
+DNA_STRUCT_RENAME_ELEM(UserDef, gp_manhattendist, gp_manhattandist)
DNA_STRUCT_RENAME_ELEM(VFont, name, filepath)
DNA_STRUCT_RENAME_ELEM(View3D, far, clip_end)
DNA_STRUCT_RENAME_ELEM(View3D, near, clip_start)
diff --git a/source/blender/makesdna/intern/dna_utils.c b/source/blender/makesdna/intern/dna_utils.c
index 97f4785374a..3cf5c52a4c6 100644
--- a/source/blender/makesdna/intern/dna_utils.c
+++ b/source/blender/makesdna/intern/dna_utils.c
@@ -235,7 +235,9 @@ void DNA_alias_maps(enum eDNA_RenameDir version_dir, GHash **r_struct_map, GHash
if (version_dir == DNA_RENAME_STATIC_FROM_ALIAS) {
const char *renames[][2] = {
- {"int8_t", "char"}, /* Note that a char is always unsigned in Blender. */
+ /* Disable 'int8_t' until we support 'signed char', since changing negative
+ * values to a different type isn't supported and will change the value. */
+ /* {"int8_t", "char"}, */
{"uint8_t", "uchar"},
{"int16_t", "short"},
{"uint16_t", "ushort"},
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index 898d2e58e45..af0d914391a 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -360,7 +360,7 @@ static int add_type(const char *str, int size)
if (str[0] == 0) {
return -1;
}
- else if (strchr(str, '*')) {
+ if (strchr(str, '*')) {
/* note: this is valid C syntax but we can't parse, complain!
* `struct SomeStruct* some_var;` <-- correct but we cant handle right now. */
return -1;
@@ -1532,12 +1532,21 @@ int main(int argc, char **argv)
#endif /* if 0 */
-/* even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit,
- * use int or int64_t instead.
+/**
+ * Disable types:
+ *
+ * - 'long': even though DNA supports, 'long' shouldn't be used since it can be either 32 or 64bit,
+ * use int, int32_t or int64_t instead.
+ * - 'int8_t': as DNA doesn't yet support 'signed char' types,
+ * all char types are assumed to be unsigned.
+ * We should be able to support this, it's just not something which has been added yet.
+ *
* Only valid use would be as a runtime variable if an API expected a long,
- * but so far we dont have this happening. */
+ * but so far we don't have this happening.
+ */
#ifdef __GNUC__
# pragma GCC poison long
+# pragma GCC poison int8_t
#endif
#include "DNA_ID.h"
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index b7f0fb87536..8781a3f448f 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -175,7 +175,7 @@ static int replace_if_different(const char *tmpfile, const char *dep_files[])
if (dep_files) {
int pass;
for (pass = 0; dep_files[pass]; pass++) {
- char from_path[4096] = __FILE__;
+ const char from_path[4096] = __FILE__;
char *p1, *p2;
/* dir only */
@@ -5147,7 +5147,7 @@ int main(int argc, char **argv)
{
int return_status = 0;
- MEM_initialize_memleak_detection();
+ MEM_init_memleak_detection();
MEM_set_error_callback(mem_error_cb);
CLG_init();
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 84f9ec749cb..11b563dae52 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -237,12 +237,27 @@ static EnumPropertyItem rna_enum_gpencil_fill_draw_modes_items[] = {
{GP_FILL_DMODE_BOTH,
"BOTH",
0,
- "Default",
+ "All",
"Use both visible strokes and edit lines as fill boundary limits"},
{GP_FILL_DMODE_STROKE, "STROKE", 0, "Strokes", "Use visible strokes as fill boundary limits"},
{GP_FILL_DMODE_CONTROL, "CONTROL", 0, "Edit Lines", "Use edit lines as fill boundary limits"},
{0, NULL, 0, NULL, NULL}};
+static EnumPropertyItem rna_enum_gpencil_fill_layers_modes_items[] = {
+ {GP_FILL_GPLMODE_VISIBLE, "VISIBLE", 0, "Visible", "Visible layers"},
+ {GP_FILL_GPLMODE_ACTIVE, "ACTIVE", 0, "Active", "Only active layer"},
+ {GP_FILL_GPLMODE_ABOVE, "ABOVE", 0, "Layer Above", "Layer above active"},
+ {GP_FILL_GPLMODE_BELOW, "BELOW", 0, "Layer Below", "Layer below active"},
+ {GP_FILL_GPLMODE_ALL_ABOVE, "ALL_ABOVE", 0, "All Above", "All layers above active"},
+ {GP_FILL_GPLMODE_ALL_BELOW, "ALL_BELOW", 0, "All Below", "All layers below active"},
+ {0, NULL, 0, NULL, NULL}};
+
+static EnumPropertyItem rna_enum_gpencil_brush_modes_items[] = {
+ {GP_BRUSH_MODE_ACTIVE, "ACTIVE", 0, "Active", "Use current mode"},
+ {GP_BRUSH_MODE_MATERIAL, "MATERIAL", 0, "Material", "Use always material mode"},
+ {GP_BRUSH_MODE_VERTEXCOLOR, "VERTEXCOLOR", 0, "Vertex Color", "Use always Vertex Color mode"},
+ {0, NULL, 0, NULL, NULL}};
+
static EnumPropertyItem rna_enum_gpencil_brush_paint_icons_items[] = {
{GP_BRUSH_ICON_PENCIL, "PENCIL", ICON_GPBRUSH_PENCIL, "Pencil", ""},
{GP_BRUSH_ICON_PEN, "PEN", ICON_GPBRUSH_PEN, "Pen", ""},
@@ -359,7 +374,7 @@ static bool rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr)
static bool rna_BrushCapabilitiesSculpt_has_persistence_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
- return br->sculpt_tool == SCULPT_TOOL_LAYER;
+ return ELEM(br->sculpt_tool, SCULPT_TOOL_LAYER, SCULPT_TOOL_CLOTH);
}
static bool rna_BrushCapabilitiesSculpt_has_pinch_factor_get(PointerRNA *ptr)
@@ -1640,6 +1655,18 @@ static void rna_def_gpencil_options(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mode", "Mode to draw boundary limits");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "fill_layer_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "fill_layer_mode");
+ RNA_def_property_enum_items(prop, rna_enum_gpencil_fill_layers_modes_items);
+ RNA_def_property_ui_text(prop, "Layer Mode", "Layers used as boundaries");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ prop = RNA_def_property(srna, "brush_draw_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "brush_draw_mode");
+ RNA_def_property_enum_items(prop, rna_enum_gpencil_brush_modes_items);
+ RNA_def_property_ui_text(prop, "Mode", "Preselected mode when using this brush");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
prop = RNA_def_property(srna, "trim", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_TRIM_STROKE);
RNA_def_property_boolean_default(prop, false);
@@ -1956,6 +1983,16 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_cloth_simulation_area_type_items[] = {
+ {BRUSH_CLOTH_SIMULATION_AREA_LOCAL,
+ "LOCAL",
+ 0,
+ "Local",
+ "Simulates only a specific area arround the brush limited by a fixed radius"},
+ {BRUSH_CLOTH_SIMULATION_AREA_GLOBAL, "GLOBAL", 0, "Global", "Simulates the entire mesh"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem brush_smooth_deform_type_items[] = {
{BRUSH_SMOOTH_DEFORM_LAPLACIAN,
"LAPLACIAN",
@@ -1973,7 +2010,7 @@ static void rna_def_brush(BlenderRNA *brna)
static const EnumPropertyItem brush_pose_deform_type_items[] = {
{BRUSH_POSE_DEFORM_ROTATE_TWIST, "ROTATE_TWIST", 0, "Rotate/Twist", ""},
{BRUSH_POSE_DEFORM_SCALE_TRASLATE, "SCALE_TRANSLATE", 0, "Scale/Translate", ""},
- {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash/Stretch", ""},
+ {BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash & Stretch", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -2126,6 +2163,14 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Force Falloff", "Shape used in the brush to apply force to the cloth");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "cloth_simulation_area_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_cloth_simulation_area_type_items);
+ RNA_def_property_ui_text(
+ prop,
+ "Simulation Area",
+ "Part of the mesh that is going to be simulated when the stroke is active");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "smooth_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_smooth_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
@@ -2556,6 +2601,15 @@ static void rna_def_brush(BlenderRNA *brna)
"Area to apply deformation falloff to the effects of the simulation");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "cloth_constraint_softbody_strength", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "cloth_constraint_softbody_strength");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_ui_text(
+ prop,
+ "Soft Body Influence",
+ "How much the simulation preserves the original shape, acting as a soft body");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "hardness", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "hardness");
RNA_def_property_range(prop, 0.0f, 1.0f);
@@ -2767,11 +2821,32 @@ static void rna_def_brush(BlenderRNA *brna)
prop, "Keep Anchor Point", "Keep the position of the last segment in the IK chain fixed");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_pose_lock_rotation", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_POSE_USE_LOCK_ROTATION);
+ RNA_def_property_ui_text(prop,
+ "Lock Rotation When Scaling",
+ "Do not rotate the segment when using the scale deform mode");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_connected_only", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_USE_CONNECTED_ONLY);
RNA_def_property_ui_text(prop, "Connected Only", "Affect only topologically connected elements");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_cloth_pin_simulation_boundary", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_PIN_SIMULATION_BOUNDARY);
+ RNA_def_property_ui_text(
+ prop,
+ "Pin Simulation Boundary",
+ "Lock the position of the vertices in the simulation falloff area to avoid artifacts and "
+ "create a softer transitionwith with unnafected areas");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
+ prop = RNA_def_property(srna, "use_cloth_collision", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_CLOTH_USE_COLLISION);
+ RNA_def_property_ui_text(prop, "Enable Collision", "Collide with objects during the simulation");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "invert_to_scrape_fill", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_INVERT_TO_SCRAPE_FILL);
RNA_def_property_ui_text(prop,
diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c
index f9275ef1993..c25cea1b4b3 100644
--- a/source/blender/makesrna/intern/rna_cachefile.c
+++ b/source/blender/makesrna/intern/rna_cachefile.c
@@ -174,6 +174,32 @@ static void rna_def_cachefile(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Object Paths", "Paths of the objects inside the Alembic archive");
+ /* ----------------- Alembic Velocity Attribute ----------------- */
+
+ prop = RNA_def_property(srna, "velocity_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_ui_text(prop,
+ "Velocity Attribute",
+ "Name of the Alembic attribute used for generating motion blur data");
+ RNA_def_property_update(prop, 0, "rna_CacheFile_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
+ static const EnumPropertyItem velocity_unit_items[] = {
+ {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""},
+ {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "velocity_unit");
+ RNA_def_property_enum_items(prop, velocity_unit_items);
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Unit",
+ "Define how the velocity vectors are interpreted with regard to time, 'frame' means "
+ "the delta time is 1 frame, 'second' means the delta time is 1 / FPS");
+ RNA_def_property_update(prop, 0, "rna_CacheFile_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
RNA_define_lib_overridable(false);
rna_def_cachefile_object_paths(brna, prop);
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 56ad8e2677b..60b6cc40792 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -702,7 +702,7 @@ static float rna_CurveMapping_evaluateF(struct CurveMapping *cumap,
static void rna_CurveMap_initialize(struct CurveMapping *cumap)
{
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
}
#else
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index c8abf774561..e6dceb5af72 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -41,7 +41,7 @@ const EnumPropertyItem rna_enum_context_mode_items[] = {
{CTX_MODE_EDIT_ARMATURE, "EDIT_ARMATURE", 0, "Armature Edit", ""},
{CTX_MODE_EDIT_METABALL, "EDIT_METABALL", 0, "Metaball Edit", ""},
{CTX_MODE_EDIT_LATTICE, "EDIT_LATTICE", 0, "Lattice Edit", ""},
- {CTX_MODE_POSE, "POSE", 0, "Pose ", ""},
+ {CTX_MODE_POSE, "POSE", 0, "Pose", ""},
{CTX_MODE_SCULPT, "SCULPT", 0, "Sculpt", ""},
{CTX_MODE_PAINT_WEIGHT, "PAINT_WEIGHT", 0, "Weight Paint", ""},
{CTX_MODE_PAINT_VERTEX, "PAINT_VERTEX", 0, "Vertex Paint", ""},
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index 771235c85aa..1768d79fe8f 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -570,7 +570,7 @@ static void rna_Curve_body_set(PointerRNA *ptr, const char *value)
Curve *cu = (Curve *)ptr->owner_id;
- cu->len_wchar = len_chars;
+ cu->len_char32 = len_chars;
cu->len = len_bytes;
cu->pos = len_chars;
@@ -1191,9 +1191,9 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_ui_text(
prop,
"Object Font",
- "Use Objects as font characters (give font objects a common name "
+ "Use objects as font characters (give font objects a common name "
"followed by the character they represent, eg. 'family-a', 'family-b', etc, "
- "set this setting to 'family-', and turn on Vertex Duplication)");
+ "set this setting to 'family-', and turn on Vertex Instancing)");
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
@@ -1206,7 +1206,7 @@ static void rna_def_font(BlenderRNA *UNUSED(brna), StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Curve_update_data");
prop = RNA_def_property(srna, "body_format", PROP_COLLECTION, PROP_NONE);
- RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_wchar");
+ RNA_def_property_collection_sdna(prop, NULL, "strinfo", "len_char32");
RNA_def_property_struct_type(prop, "TextCharacterFormat");
RNA_def_property_ui_text(prop, "Character Info", "Stores the style of each character");
diff --git a/source/blender/makesrna/intern/rna_curveprofile.c b/source/blender/makesrna/intern/rna_curveprofile.c
index ce91fc79085..ee1c659fcd5 100644
--- a/source/blender/makesrna/intern/rna_curveprofile.c
+++ b/source/blender/makesrna/intern/rna_curveprofile.c
@@ -146,7 +146,7 @@ static void rna_CurveProfile_evaluate(struct CurveProfile *profile,
static void rna_CurveProfile_initialize(struct CurveProfile *profile, int segments_len)
{
- BKE_curveprofile_initialize(profile, (short)segments_len);
+ BKE_curveprofile_init(profile, (short)segments_len);
}
static void rna_CurveProfile_update(struct CurveProfile *profile)
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index 3ae16f8577a..d5449a69cf6 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1635,7 +1635,7 @@ static void rna_def_fmodifier(BlenderRNA *brna)
/* TODO: setting this to true must ensure that all others in stack are turned off too... */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_ACTIVE);
- RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited ");
+ RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited");
RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_active_set");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_active_update");
RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1);
diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c
index 47e0333edb1..0a58f8af593 100644
--- a/source/blender/makesrna/intern/rna_fluid.c
+++ b/source/blender/makesrna/intern/rna_fluid.c
@@ -1681,7 +1681,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_range(prop, 0.001, 1.0);
RNA_def_property_ui_range(prop, 0.01, 1.0, 0.05, -1);
RNA_def_property_ui_text(prop,
- "Obstacle-Fluid Threshold ",
+ "Obstacle-Fluid Threshold",
"Determines how much fluid is allowed in an obstacle cell "
"(higher values will tag a boundary cell as an obstacle easier "
"and reduce the boundary smoothening effect)");
@@ -2052,6 +2052,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop,
"Start",
"Frame on which the simulation starts. This is the first frame that will be baked");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_end", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_end");
@@ -2061,6 +2062,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop,
"End",
"Frame on which the simulation stops. This is the last frame that will be baked");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_offset", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_offset");
@@ -2070,6 +2072,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Offset",
"Frame offset that is used when loading the simulation from the cache. It is not considered "
"when baking the simulation, only when loading it");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "cache_frame_pause_data", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "cache_frame_pause_data");
@@ -2093,6 +2096,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_mesh_set", "rna_Fluid_cachetype_mesh_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching surface data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_meshcache_reset");
prop = RNA_def_property(srna, "cache_data_format", PROP_ENUM, PROP_NONE);
@@ -2102,6 +2106,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_data_set", "rna_Fluid_cachetype_volume_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching volumetric data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "cache_particle_format", PROP_ENUM, PROP_NONE);
@@ -2111,6 +2116,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_particle_set", "rna_Fluid_cachetype_particle_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching particle data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_particlescache_reset");
prop = RNA_def_property(srna, "cache_noise_format", PROP_ENUM, PROP_NONE);
@@ -2120,6 +2126,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
prop, NULL, "rna_Fluid_cachetype_noise_set", "rna_Fluid_cachetype_volume_itemf");
RNA_def_property_ui_text(
prop, "File Format", "Select the file format to be used for caching noise data");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_noisecache_reset");
prop = RNA_def_property(srna, "cache_type", PROP_ENUM, PROP_NONE);
@@ -2127,6 +2134,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
RNA_def_property_enum_items(prop, cache_types);
RNA_def_property_enum_funcs(prop, NULL, "rna_Fluid_cachetype_set", NULL);
RNA_def_property_ui_text(prop, "Type", "Change the cache type of the simulation");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Fluid_domain_data_reset");
prop = RNA_def_property(srna, "cache_resumable", PROP_BOOLEAN, PROP_NONE);
@@ -2137,6 +2145,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna)
"Additional data will be saved so that the bake jobs can be resumed after pausing. Because "
"more data will be written to disk it is recommended to avoid enabling this option when "
"baking at high resolutions");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_datacache_reset");
prop = RNA_def_property(srna, "cache_directory", PROP_STRING, PROP_DIRPATH);
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 887bded8540..1c43815d3a2 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -67,7 +67,6 @@ static const EnumPropertyItem image_source_items[] = {
# include "BKE_global.h"
-# include "GPU_draw.h"
# include "GPU_texture.h"
# include "IMB_imbuf.h"
@@ -200,7 +199,7 @@ static void rna_Image_gpu_texture_update(Main *UNUSED(bmain),
Image *ima = (Image *)ptr->owner_id;
if (!G.background) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
@@ -398,7 +397,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
static int rna_Image_bindcode_get(PointerRNA *ptr)
{
Image *ima = (Image *)ptr->data;
- GPUTexture *tex = ima->gputexture[TEXTARGET_TEXTURE_2D][0];
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
return (tex) ? GPU_texture_opengl_bindcode(tex) : 0;
}
@@ -516,7 +515,7 @@ static void rna_Image_pixels_set(PointerRNA *ptr, const float *values)
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID | IB_MIPMAP_INVALID;
BKE_image_mark_dirty(ima, ibuf);
if (!G.background) {
- GPU_free_image(ima);
+ BKE_image_free_gputextures(ima);
}
WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id);
}
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 41c0e724234..6f876923e52 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -50,8 +50,6 @@
# include "DNA_image_types.h"
# include "DNA_scene_types.h"
-# include "GPU_glew.h"
-
# include "MEM_guardedalloc.h"
static void rna_ImagePackedFile_save(ImagePackedFile *imapf, Main *bmain, ReportList *reports)
@@ -222,23 +220,24 @@ static int rna_Image_gl_load(Image *image, ReportList *reports, int frame)
BKE_imageuser_default(&iuser);
iuser.framenr = frame;
- GPUTexture *tex = GPU_texture_from_blender(image, &iuser, NULL, GL_TEXTURE_2D);
+ GPUTexture *tex = BKE_image_get_gpu_texture(image, &iuser, NULL);
if (tex == NULL) {
BKE_reportf(reports, RPT_ERROR, "Failed to load image texture '%s'", image->id.name + 2);
- return (int)GL_INVALID_OPERATION;
+ /* TODO(fclem) this error code makes no sense for vulkan. */
+ return 0x0502; /* GL_INVALID_OPERATION */
}
- return GL_NO_ERROR;
+ return 0; /* GL_NO_ERROR */
}
static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
{
- int error = GL_NO_ERROR;
+ int error = 0; /* GL_NO_ERROR */
BKE_image_tag_time(image);
- if (image->gputexture[TEXTARGET_TEXTURE_2D] == NULL) {
+ if (image->gputexture[TEXTARGET_2D][0] == NULL) {
error = rna_Image_gl_load(image, reports, frame);
}
@@ -247,7 +246,7 @@ static int rna_Image_gl_touch(Image *image, ReportList *reports, int frame)
static void rna_Image_gl_free(Image *image)
{
- GPU_free_image(image);
+ BKE_image_free_gputextures(image);
/* remove the nocollect flag, image is available for garbage collection again */
image->flag &= ~IMA_NOCOLLECT;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 86f05c350f3..05e11ffc919 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -302,7 +302,7 @@ const EnumPropertyItem rna_enum_modifier_triangulate_quad_method_items[] = {
{MOD_TRIANGULATE_QUAD_BEAUTY,
"BEAUTY",
0,
- "Beauty ",
+ "Beauty",
"Split the quads in nice triangles, slower method"},
{MOD_TRIANGULATE_QUAD_FIXED,
"FIXED",
@@ -1163,7 +1163,7 @@ static void rna_BevelModifier_update_segments(Main *bmain, Scene *scene, Pointer
BevelModifierData *bmd = (BevelModifierData *)ptr->data;
if (RNA_enum_get(ptr, "profile_type") == MOD_BEVEL_PROFILE_CUSTOM) {
short segments = (short)RNA_int_get(ptr, "segments");
- BKE_curveprofile_initialize(bmd->custom_profile, segments);
+ BKE_curveprofile_init(bmd->custom_profile, segments);
}
rna_Modifier_update(bmain, scene, ptr);
}
@@ -1699,6 +1699,51 @@ static bool rna_Modifier_show_expanded_get(PointerRNA *ptr)
return md->ui_expand_flag & (1 << 0);
}
+static int rna_MeshSequenceCacheModifier_has_velocity_get(PointerRNA *ptr)
+{
+# ifdef WITH_ALEMBIC
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
+ return ABC_has_vec3_array_property_named(mcmd->reader, mcmd->cache_file->velocity_name);
+# else
+ return false;
+ UNUSED_VARS(ptr);
+# endif
+}
+
+static int rna_MeshSequenceCacheModifier_read_velocity_get(PointerRNA *ptr)
+{
+# ifdef WITH_ALEMBIC
+ MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)ptr->data;
+
+ if (mcmd->num_vertices == 0) {
+ return 0;
+ }
+
+ if (mcmd->vertex_velocities) {
+ MEM_freeN(mcmd->vertex_velocities);
+ }
+
+ mcmd->vertex_velocities = MEM_mallocN(sizeof(MeshCacheVertexVelocity) * mcmd->num_vertices,
+ "Mesh Cache Velocities");
+
+ int num_read = ABC_read_velocity_cache(mcmd->reader,
+ mcmd->cache_file->velocity_name,
+ mcmd->last_lookup_time,
+ mcmd->velocity_scale * mcmd->velocity_delta,
+ mcmd->num_vertices,
+ (float *)mcmd->vertex_velocities);
+
+ if (num_read == -1 || num_read != mcmd->num_vertices) {
+ return false;
+ }
+
+ return true;
+# else
+ return false;
+ UNUSED_VARS(ptr);
+# endif
+}
+
#else
/* NOTE: *MUST* return subdivision_type property. */
@@ -5667,7 +5712,17 @@ static void rna_def_modifier_ocean(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 1, 1024);
RNA_def_property_ui_range(prop, 1, 32, 1, -1);
- RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
+ RNA_def_property_ui_text(
+ prop, "Render Resolution", "Resolution of the generated surface for rendering and baking");
+ RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
+
+ prop = RNA_def_property(srna, "viewport_resolution", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "viewport_resolution");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_range(prop, 1, 1024);
+ RNA_def_property_ui_range(prop, 1, 32, 1, -1);
+ RNA_def_property_ui_text(
+ prop, "Viewport Resolution", "Viewport resolution of the generated surface");
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
prop = RNA_def_property(srna, "spatial_size", PROP_INT, PROP_NONE);
@@ -5905,7 +5960,7 @@ static void rna_def_modifier_triangulate(BlenderRNA *brna)
static void rna_def_modifier_meshcache(BlenderRNA *brna)
{
static const EnumPropertyItem prop_format_type_items[] = {
- {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD ", ""},
+ {MOD_MESHCACHE_TYPE_MDD, "MDD", 0, "MDD", ""},
{MOD_MESHCACHE_TYPE_PC2, "PC2", 0, "PC2", ""},
{0, NULL, 0, NULL, NULL},
};
@@ -5926,7 +5981,7 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
};
static const EnumPropertyItem prop_interpolation_type_items[] = {
- {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None ", ""},
+ {MOD_MESHCACHE_INTERP_NONE, "NONE", 0, "None", ""},
{MOD_MESHCACHE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
/* for cardinal we'd need to read 4x cache's */
// {MOD_MESHCACHE_INTERP_CARDINAL, "CARDINAL", 0, "Cardinal", ""},
@@ -6066,6 +6121,22 @@ static void rna_def_modifier_meshcache(BlenderRNA *brna)
RNA_define_lib_overridable(false);
}
+static void rna_def_mesh_cache_velocities(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "MeshCacheVertexVelocity", NULL);
+ RNA_def_struct_ui_text(srna, "Mesh Cache Velocity", "Velocity attribute of an Alembic mesh");
+ RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL);
+
+ prop = RNA_def_property(srna, "velocity", PROP_FLOAT, PROP_VELOCITY);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_sdna(prop, NULL, "vel");
+ RNA_def_property_ui_text(prop, "Velocity", "");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+}
+
static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
{
StructRNA *srna;
@@ -6108,6 +6179,35 @@ static void rna_def_modifier_meshseqcache(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "velocity_scale");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(
+ prop,
+ "Velocity Scale",
+ "Multiplier used to control the magnitude of the velocity vectors for time effects");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* -------------------------- Velocity Vectors -------------------------- */
+
+ prop = RNA_def_property(srna, "vertex_velocities", PROP_COLLECTION, PROP_NONE);
+ RNA_def_property_collection_sdna(prop, NULL, "vertex_velocities", "num_vertices");
+ RNA_def_property_struct_type(prop, "MeshCacheVertexVelocity");
+ RNA_def_property_ui_text(
+ prop, "Fluid Mesh Vertices", "Vertices of the fluid mesh generated by simulation");
+
+ rna_def_mesh_cache_velocities(brna);
+
+ prop = RNA_def_property(srna, "has_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Has Velocity Cache", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_has_velocity_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "read_velocity", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Read Velocity Cache", "");
+ RNA_def_property_boolean_funcs(prop, "rna_MeshSequenceCacheModifier_read_velocity_get", NULL);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
RNA_define_lib_overridable(false);
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 3eb2c15c053..af07185ab4a 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -38,6 +38,7 @@
#include "BKE_animsys.h"
#include "BKE_image.h"
#include "BKE_node.h"
+#include "BKE_simulation.h"
#include "BKE_texture.h"
#include "RNA_access.h"
@@ -2848,6 +2849,14 @@ static void rna_NodeSocketStandard_value_update(struct bContext *C, PointerRNA *
}
}
+static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, PointerRNA *ptr)
+{
+ rna_NodeSocketStandard_value_update(C, ptr);
+ bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
+ Main *bmain = CTX_data_main(C);
+ ntreeUpdateTree(bmain, ntree);
+}
+
/* ******** Node Types ******** */
static void rna_NodeInternalSocketTemplate_name_get(PointerRNA *ptr, char *value)
@@ -6495,7 +6504,7 @@ static void def_cmp_channel_matte(StructRNA *srna)
static const EnumPropertyItem algorithm_items[] = {
{0, "SINGLE", 0, "Single", "Limit by single channel"},
- {1, "MAX", 0, "Max", "Limit by max of other channels "},
+ {1, "MAX", 0, "Max", "Limit by max of other channels"},
{0, NULL, 0, NULL, NULL},
};
@@ -8868,7 +8877,8 @@ static void rna_def_node_socket_object(BlenderRNA *brna,
RNA_def_property_pointer_sdna(prop, NULL, "value");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
+ RNA_def_property_update(
+ prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
/* socket interface */
@@ -8902,7 +8912,8 @@ static void rna_def_node_socket_image(BlenderRNA *brna,
RNA_def_property_pointer_sdna(prop, NULL, "value");
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update");
+ RNA_def_property_update(
+ prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_and_relation_update");
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT | PROP_CONTEXT_UPDATE);
/* socket interface */
@@ -9916,7 +9927,7 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER);
RNA_def_property_ui_text(
- prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop");
+ prop, "Viewer Region", "Use boundaries for viewer nodes and composite backdrop");
RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update");
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 84b83bee089..08ca3f16b6d 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -193,6 +193,12 @@ static EnumPropertyItem instance_items_nogroup[] = {
INSTANCE_ITEMS_SHARED,
{0, NULL, 0, NULL, NULL},
};
+
+static EnumPropertyItem instance_items_pointcloud[] = {
+ {0, "NONE", 0, "None", ""},
+ {OB_DUPLIVERTS, "POINTS", 0, "Points", "Instantiate child objects on all points"},
+ {0, NULL, 0, NULL, NULL},
+};
#endif
#undef INSTANCE_ITEMS_SHARED
#undef INSTANCE_ITEM_COLLECTION
@@ -707,6 +713,9 @@ static const EnumPropertyItem *rna_Object_instance_type_itemf(bContext *UNUSED(C
if (ob->type == OB_EMPTY) {
item = instance_items;
}
+ else if (ob->type == OB_POINTCLOUD) {
+ item = instance_items_pointcloud;
+ }
else {
item = instance_items_nogroup;
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index af1f1847fc6..3067a5a9453 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -2887,7 +2887,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "userjit");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_range(prop, 0, 1000);
- RNA_def_property_ui_text(prop, "P/F", "Emission locations / face (0 = automatic)");
+ RNA_def_property_ui_text(prop, "Particles/Face", "Emission locations per face (0 = automatic)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop = RNA_def_property(srna, "grid_resolution", PROP_INT, PROP_UNSIGNED);
diff --git a/source/blender/makesrna/intern/rna_rigidbody.c b/source/blender/makesrna/intern/rna_rigidbody.c
index 325c4e3caa9..450d148d8a3 100644
--- a/source/blender/makesrna/intern/rna_rigidbody.c
+++ b/source/blender/makesrna/intern/rna_rigidbody.c
@@ -75,6 +75,11 @@ const EnumPropertyItem rna_enum_rigidbody_object_shape_items[] = {
"Mesh",
"Mesh consisting of triangles only, allowing for more detailed interactions than convex "
"hulls"},
+ {RB_SHAPE_COMPOUND,
+ "COMPOUND",
+ ICON_MESH_DATA,
+ "Compound Parent",
+ "Combines all of its direct rigid body children into one rigid object."},
{0, NULL, 0, NULL, NULL},
};
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 66698d60423..262c9f87b66 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -2862,7 +2862,7 @@ static void rna_def_tool_settings(BlenderRNA *brna)
"3D Cursor",
"Draw stroke at 3D cursor location"},
/* Weird, GP_PROJECT_VIEWALIGN is inverted. */
- {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view "},
+ {0, "VIEW", ICON_RESTRICT_VIEW_ON, "View", "Stick stroke to the view"},
{GP_PROJECT_VIEWSPACE | GP_PROJECT_DEPTH_VIEW,
"SURFACE",
ICON_FACESEL,
@@ -3589,7 +3589,7 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, brush_size_unit_items);
RNA_def_property_ui_text(
- prop, "Radius Unit", "Measure brush size relative to the view or the scene ");
+ prop, "Radius Unit", "Measure brush size relative to the view or the scene");
}
static void rna_def_curve_paint_settings(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index a66e20258d2..06c73fbb19c 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -138,8 +138,7 @@ static void rna_SceneRender_get_frame_path(
}
static void rna_Scene_ray_cast(Scene *scene,
- Main *bmain,
- ViewLayer *view_layer,
+ Depsgraph *depsgraph,
float origin[3],
float direction[3],
float ray_dist,
@@ -151,8 +150,6 @@ static void rna_Scene_ray_cast(Scene *scene,
float r_obmat[16])
{
normalize_v3(direction);
-
- Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true);
SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, 0);
bool ret = ED_transform_snap_object_project_ray_ex(sctx,
@@ -292,9 +289,9 @@ void RNA_api_scene(StructRNA *srna)
/* Ray Cast */
func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast");
- RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
- parm = RNA_def_pointer(func, "view_layer", "ViewLayer", "", "Scene Layer");
+
+ parm = RNA_def_pointer(func, "depsgraph", "Depsgraph", "", "The current dependency graph");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
/* ray start and end */
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c
index 24c4818694f..fb2a60db0fd 100644
--- a/source/blender/makesrna/intern/rna_screen.c
+++ b/source/blender/makesrna/intern/rna_screen.c
@@ -231,7 +231,7 @@ static int rna_Area_ui_type_get(PointerRNA *ptr)
* the area type is changing.
* So manually do the lookup in those cases, but do not actually change area->type
* since that prevents a proper exit when the area type is changing.
- * Logic copied from `ED_area_initialize()`.*/
+ * Logic copied from `ED_area_init()`.*/
SpaceType *type = area->type;
if (type == NULL || area_changing) {
type = BKE_spacetype_from_id(area_type);
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 4157747455d..59cedf8fcb8 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -370,13 +370,14 @@ static void rna_Sequences_remove(
Sequence *seq = seq_ptr->data;
Scene *scene = (Scene *)id;
- if (BLI_remlink_safe(&ed->seqbase, seq) == false) {
+ if (BLI_findindex(&ed->seqbase, seq) == -1) {
BKE_reportf(
reports, RPT_ERROR, "Sequence '%s' not in scene '%s'", seq->name + 2, scene->id.name + 2);
return;
}
- BKE_sequence_free(scene, seq, true);
+ BKE_sequencer_flag_for_removal(scene, &ed->seqbase, seq);
+ BKE_sequencer_remove_flagged_sequences(scene, &ed->seqbase);
RNA_POINTER_INVALIDATE(seq_ptr);
DEG_relations_tag_update(bmain);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 494fcec4c31..155f5ab3043 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1776,87 +1776,28 @@ static const EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSE
{
SpaceProperties *sbuts = (SpaceProperties *)(ptr->data);
EnumPropertyItem *item = NULL;
- int totitem = 0;
-
- if (sbuts->pathflag & (1 << BCONTEXT_TOOL)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TOOL);
- }
-
- if (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_OUTPUT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OUTPUT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_VIEW_LAYER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_VIEW_LAYER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD);
- }
- if (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_SHADERFX)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SHADERFX);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_DATA)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA);
- (item + totitem - 1)->icon = sbuts->dataicon;
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_BONE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT);
- }
-
- if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL);
- }
+ /* We use 32 tabs maximum here so a flag for each can fit into a 32 bit integer flag.
+ * A theoretical maximum would be BCONTEXT_TOT * 2, with every tab displayed and a spacer
+ * in every other item. But this size is currently limited by the size of integer
+ * supported by RNA enums. */
+ int context_tabs_array[32];
+ int totitem = ED_buttons_tabs_list(sbuts, context_tabs_array);
+ BLI_assert(totitem <= ARRAY_SIZE(context_tabs_array));
+
+ int totitem_added = 0;
+ for (int i = 0; i < totitem; i++) {
+ if (context_tabs_array[i] == -1) {
+ RNA_enum_item_add_separator(&item, &totitem_added);
+ continue;
+ }
- if (totitem) {
- RNA_enum_item_add_separator(&item, &totitem);
- }
+ RNA_enum_items_add_value(&item, &totitem_added, buttons_context_items, context_tabs_array[i]);
- if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) {
- RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE);
+ /* Add the object data icon dynamically for the data tab. */
+ if (context_tabs_array[i] == BCONTEXT_DATA) {
+ (item + totitem_added - 1)->icon = sbuts->dataicon;
+ }
}
RNA_enum_item_end(&item, &totitem);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 00bbff5cf51..0567b22d23f 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -179,6 +179,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
# include "BKE_blender.h"
# include "BKE_global.h"
# include "BKE_idprop.h"
+# include "BKE_image.h"
# include "BKE_main.h"
# include "BKE_mesh_runtime.h"
# include "BKE_paint.h"
@@ -187,9 +188,9 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = {
# include "DEG_depsgraph.h"
-# include "GPU_draw.h"
# include "GPU_extensions.h"
# include "GPU_select.h"
+# include "GPU_texture.h"
# include "BLF_api.h"
@@ -363,13 +364,14 @@ static void rna_userdef_load_ui_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
static void rna_userdef_anisotropic_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- GPU_set_anisotropic(U.anisotropic_filter);
+ GPU_samplers_free();
+ GPU_samplers_init();
rna_userdef_update(bmain, scene, ptr);
}
static void rna_userdef_gl_texture_limit_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
- GPU_free_images(bmain);
+ BKE_image_free_all_gputextures(bmain);
rna_userdef_update(bmain, scene, ptr);
}
@@ -4593,7 +4595,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
"no matter opening direction");
static const EnumPropertyItem header_align_items[] = {
- {0, "NONE", 0, "Default", "Keep existing header alignment"},
+ {0, "NONE", 0, "Keep Existing", "Keep existing header alignment"},
{USER_HEADER_FROM_PREF, "TOP", 0, "Top", "Top aligned on load"},
{USER_HEADER_FROM_PREF | USER_HEADER_BOTTOM,
"BOTTOM",
@@ -4988,7 +4990,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil_manhattan_distance", PROP_INT, PROP_PIXEL);
- RNA_def_property_int_sdna(prop, NULL, "gp_manhattendist");
+ RNA_def_property_int_sdna(prop, NULL, "gp_manhattandist");
RNA_def_property_range(prop, 0, 100);
RNA_def_property_ui_text(prop,
"Grease Pencil Manhattan Distance",
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 48d69f8e02c..1c98cec915e 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -139,12 +139,11 @@ static int svert_sum_cmp(const void *e1, const void *e2)
if (sv1->sum_co > sv2->sum_co) {
return 1;
}
- else if (sv1->sum_co < sv2->sum_co) {
+ if (sv1->sum_co < sv2->sum_co) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static void svert_from_mvert(SortVertsElem *sv,
@@ -826,10 +825,10 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
if (amd->curve_ob && amd->curve_ob->type != OB_CURVE) {
return true;
}
- else if (amd->start_cap && amd->start_cap->type != OB_MESH) {
+ if (amd->start_cap && amd->start_cap->type != OB_MESH) {
return true;
}
- else if (amd->end_cap && amd->end_cap->type != OB_MESH) {
+ if (amd->end_cap && amd->end_cap->type != OB_MESH) {
return true;
}
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 9b9dd0a079c..191623112bb 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -103,9 +103,8 @@ static bool dependsOnTime(ModifierData *md)
if (dmd->texture) {
return BKE_texture_dependsOnTime(dmd->texture);
}
- else {
- return false;
- }
+
+ return false;
}
static bool dependsOnNormals(ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index 4e46e135b72..d520cccf0a2 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -1180,9 +1180,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BKE_id_free(NULL, split_m);
return explode;
}
- else {
- return explodeMesh(emd, psmd, ctx, scene, mesh);
- }
+
+ return explodeMesh(emd, psmd, ctx, scene, mesh);
}
return mesh;
}
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 083348dfb26..86592245368 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -185,7 +185,7 @@ static float hook_falloff(const struct HookData_cb *hd, const float len_sq)
if (len_sq > hd->falloff_sq) {
return 0.0f;
}
- else if (len_sq > 0.0f) {
+ if (len_sq > 0.0f) {
float fac;
if (hd->falloff_type == eHook_Falloff_Const) {
@@ -304,7 +304,7 @@ static void deformVerts_do(HookModifierData *hmd,
}
if (hmd->curfalloff) {
- BKE_curvemapping_initialize(hmd->curfalloff);
+ BKE_curvemapping_init(hmd->curfalloff);
}
/* Generic data needed for applying per-vertex calculations (initialize all members) */
diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc
index 93fb7749392..7b09d3c470d 100644
--- a/source/blender/modifiers/intern/MOD_mask.cc
+++ b/source/blender/modifiers/intern/MOD_mask.cc
@@ -44,12 +44,7 @@
#include "BKE_lib_query.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
-
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
#include "BKE_screen.h"
-#undef new
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
index 60376f61708..6787ef5b47e 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -238,22 +238,19 @@ bool MOD_meshcache_read_mdd_frame(FILE *fp,
MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) {
return true;
}
- else {
- return false;
- }
+
+ return false;
}
- else {
- /* read both and interpolate */
- if ((BLI_fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
- (BLI_fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
- return true;
- }
- else {
- return false;
- }
+
+ /* read both and interpolate */
+ if ((BLI_fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (BLI_fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_mdd_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
+ return true;
}
+
+ return false;
}
bool MOD_meshcache_read_mdd_times(const char *filepath,
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 60011458c67..1ea71730db7 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -213,22 +213,19 @@ bool MOD_meshcache_read_pc2_frame(FILE *fp,
MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str)) {
return true;
}
- else {
- return false;
- }
+
+ return false;
}
- else {
- /* read both and interpolate */
- if ((BLI_fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
- (BLI_fseek(fp, 0, SEEK_SET) == 0) &&
- MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
- return true;
- }
- else {
- return false;
- }
+
+ /* read both and interpolate */
+ if ((BLI_fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[0], 1.0f, err_str) &&
+ (BLI_fseek(fp, 0, SEEK_SET) == 0) &&
+ MOD_meshcache_read_pc2_index(fp, vertexCos, verts_tot, index_range[1], factor, err_str)) {
+ return true;
}
+
+ return false;
}
bool MOD_meshcache_read_pc2_times(const char *filepath,
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 8f6676dd0b2..5513e6b4971 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -33,6 +33,8 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "MEM_guardedalloc.h"
+
#include "BKE_cachefile.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
@@ -65,6 +67,9 @@ static void initData(ModifierData *md)
mcmd->cache_file = NULL;
mcmd->object_path[0] = '\0';
mcmd->read_flag = MOD_MESHSEQ_READ_ALL;
+ mcmd->velocity_scale = 1.0f;
+ mcmd->vertex_velocities = NULL;
+ mcmd->num_vertices = 0;
mcmd->reader = NULL;
mcmd->reader_object_path[0] = '\0';
@@ -91,6 +96,10 @@ static void freeData(ModifierData *md)
mcmd->reader_object_path[0] = '\0';
BKE_cachefile_reader_free(mcmd->cache_file, &mcmd->reader);
}
+
+ if (mcmd->vertex_velocities) {
+ MEM_freeN(mcmd->vertex_velocities);
+ }
}
static bool isDisabled(const struct Scene *UNUSED(scene),
@@ -154,6 +163,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Mesh *result = ABC_read_mesh(mcmd->reader, ctx->object, mesh, time, &err_str, mcmd->read_flag);
+ mcmd->velocity_delta = 1.0f;
+ if (mcmd->cache_file->velocity_unit == CACHEFILE_VELOCITY_UNIT_SECOND) {
+ mcmd->velocity_delta /= FPS;
+ }
+
+ mcmd->last_lookup_time = time;
+
+ if (result != NULL) {
+ mcmd->num_vertices = result->totvert;
+ }
+
if (err_str) {
BKE_modifier_set_error(md, "%s", err_str);
}
@@ -221,6 +241,8 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(layout, &ptr, "read_data", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
}
+ uiItemR(layout, &ptr, "velocity_scale", 0, NULL, ICON_NONE);
+
modifier_panel_end(layout, &ptr);
}
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index 7039b24cfc6..66ab6b9e4db 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -472,7 +472,7 @@ static bool is_valid_target(NormalEditModifierData *enmd)
if (enmd->mode == MOD_NORMALEDIT_MODE_RADIAL) {
return true;
}
- else if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
+ if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) {
return true;
}
BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings");
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 6374f081581..7b31886a220 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -59,7 +59,7 @@
#include "MOD_ui_common.h"
#ifdef WITH_OCEANSIM
-static void init_cache_data(Object *ob, struct OceanModifierData *omd)
+static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution)
{
const char *relbase = BKE_modifier_path_relbase_from_global(ob);
@@ -71,7 +71,7 @@ static void init_cache_data(Object *ob, struct OceanModifierData *omd)
omd->chop_amount,
omd->foam_coverage,
omd->foam_fade,
- omd->resolution);
+ resolution);
}
static void simulate_ocean_modifier(struct OceanModifierData *omd)
@@ -87,7 +87,11 @@ static void initData(ModifierData *md)
#ifdef WITH_OCEANSIM
OceanModifierData *omd = (OceanModifierData *)md;
+ /* Render resolution */
omd->resolution = 7;
+ /* Display resolution for the non-render case */
+ omd->viewport_resolution = 7;
+
omd->spatial_size = 50;
omd->wave_alignment = 0.0;
@@ -126,7 +130,7 @@ static void initData(ModifierData *md)
omd->spraylayername[0] = '\0'; /* layer name empty by default */
omd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(omd->ocean, omd);
+ BKE_ocean_init_from_modifier(omd->ocean, omd, omd->viewport_resolution);
simulate_ocean_modifier(omd);
#else /* WITH_OCEANSIM */
/* unused */
@@ -164,7 +168,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla
tomd->oceancache = NULL;
tomd->ocean = BKE_ocean_add();
- BKE_ocean_init_from_modifier(tomd->ocean, tomd);
+ BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution);
simulate_ocean_modifier(tomd);
#else /* WITH_OCEANSIM */
/* unused */
@@ -288,7 +292,7 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata,
}
}
-static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
+static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, const int resolution)
{
Mesh *result;
@@ -297,10 +301,10 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig)
int num_verts;
int num_polys;
- const bool use_threading = omd->resolution > 4;
+ const bool use_threading = resolution > 4;
- gogd.rx = omd->resolution * omd->resolution;
- gogd.ry = omd->resolution * omd->resolution;
+ gogd.rx = resolution * resolution;
+ gogd.ry = resolution * resolution;
gogd.res_x = gogd.rx * omd->repeat_x;
gogd.res_y = gogd.ry * omd->repeat_y;
@@ -362,6 +366,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
Mesh *result = NULL;
OceanResult ocr;
+ const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution :
+ omd->viewport_resolution;
+
MVert *mverts;
int cfra_for_cache;
@@ -383,7 +390,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
/* do ocean simulation */
if (omd->cached == true) {
if (!omd->oceancache) {
- init_cache_data(ob, omd);
+ init_cache_data(ob, omd, resolution);
}
BKE_ocean_simulate_cache(omd->oceancache, cfra_scene);
}
@@ -393,12 +400,12 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes
* This function is only called on an original object when applying the modifier
* using the 'Apply Modifier' button, and thus it is not called frequently for
* simulation. */
- allocated_ocean |= BKE_ocean_ensure(omd);
+ allocated_ocean |= BKE_ocean_ensure(omd, resolution);
simulate_ocean_modifier(omd);
}
if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) {
- result = generate_ocean_geometry(omd, mesh);
+ result = generate_ocean_geometry(omd, mesh, resolution);
BKE_mesh_ensure_normals(result);
}
else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
@@ -558,7 +565,10 @@ static void panel_draw(const bContext *C, Panel *panel)
uiItemR(sub, &ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE);
uiItemR(sub, &ptr, "repeat_y", 0, IFACE_("Y"), ICON_NONE);
}
- uiItemR(col, &ptr, "resolution", 0, NULL, ICON_NONE);
+
+ sub = uiLayoutColumn(col, true);
+ uiItemR(sub, &ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE);
+ uiItemR(sub, &ptr, "resolution", 0, IFACE_("Render"), ICON_NONE);
uiItemR(col, &ptr, "time", 0, NULL, ICON_NONE);
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index dd881f1ac74..d3d2f891929 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -198,12 +198,11 @@ static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *ps
if (maxp > minp) {
return randp < minp || randp >= maxp;
}
- else if (maxp < minp) {
+ if (maxp < minp) {
return randp < minp && randp >= maxp;
}
- else {
- return true;
- }
+
+ return true;
return false;
}
@@ -443,7 +442,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
float angle = 2.0f * M_PI *
(pimd->rotation +
pimd->random_rotation * (psys_frand(psys, 19957323 + p) - 0.5f));
- float eul[3] = {0.0f, 0.0f, angle};
+ const float eul[3] = {0.0f, 0.0f, angle};
float rot[4];
eul_to_quat(rot, eul);
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index b9bb7add811..3bb7ecd43f4 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -301,7 +301,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
float totlen = len_v3(mtx_tx[3]);
if (totlen != 0.0f) {
- float zero[3] = {0.0f, 0.0f, 0.0f};
+ const float zero[3] = {0.0f, 0.0f, 0.0f};
float cp[3];
screw_ofs = closest_to_line_v3(cp, mtx_tx[3], zero, axis_vec);
}
@@ -412,7 +412,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert);
if (mloopuv_layers_tot) {
- float zero_co[3] = {0};
+ const float zero_co[3] = {0};
plane_from_point_normal_v3(uv_axis_plane, zero_co, axis_vec);
}
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index a5f6be04a08..c40fbffc506 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -96,7 +96,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene),
if (!smd->target || smd->target->type != OB_MESH) {
return true;
}
- else if (smd->auxTarget && smd->auxTarget->type != OB_MESH) {
+ if (smd->auxTarget && smd->auxTarget->type != OB_MESH) {
return true;
}
return false;
diff --git a/source/blender/modifiers/intern/MOD_simulation.cc b/source/blender/modifiers/intern/MOD_simulation.cc
index d9cc9840e08..92ad02ae34a 100644
--- a/source/blender/modifiers/intern/MOD_simulation.cc
+++ b/source/blender/modifiers/intern/MOD_simulation.cc
@@ -46,16 +46,11 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_pointcloud.h"
+#include "BKE_screen.h"
#include "BKE_simulation.h"
#include "BLO_read_write.h"
-/* SpaceType struct has a member called 'new' which obviously conflicts with C++
- * so temporarily redefining the new keyword to make it compile. */
-#define new extern_new
-#include "BKE_screen.h"
-#undef new
-
#include "UI_interface.h"
#include "UI_resources.h"
@@ -114,10 +109,12 @@ static PointCloud *modifyPointCloud(ModifierData *md,
const float3 *positions = (const float3 *)CustomData_get_layer_named(
&state->attributes, CD_PROP_FLOAT3, "Position");
+ const float *radii = (const float *)CustomData_get_layer_named(
+ &state->attributes, CD_PROP_FLOAT, "Radius");
memcpy(pointcloud->co, positions, sizeof(float3) * state->tot_particles);
for (int i = 0; i < state->tot_particles; i++) {
- pointcloud->radius[i] = 0.03f;
+ pointcloud->radius[i] = radii[i];
}
return pointcloud;
@@ -131,6 +128,9 @@ static void panel_draw(const bContext *C, Panel *panel)
PointerRNA ob_ptr;
modifier_panel_get_property_pointers(C, panel, &ob_ptr, &ptr);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
uiItemR(layout, &ptr, "simulation", 0, NULL, ICON_NONE);
uiItemR(layout, &ptr, "data_path", 0, NULL, ICON_NONE);
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 8f0174fe6d9..1bf07bdefbb 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -222,9 +222,8 @@ static bool skin_frame_find_contained_faces(const Frame *frame, BMFace *fill_fac
if (diag) {
return BM_edge_face_pair(diag, &fill_faces[0], &fill_faces[1]);
}
- else {
- return false;
- }
+
+ return false;
}
/* Returns true if hull is successfully built, false otherwise */
@@ -460,7 +459,7 @@ static void node_frames_init(SkinNode *nf, int totframe)
}
static void create_frame(
- Frame *frame, const float co[3], const float radius[2], float mat[3][3], float offset)
+ Frame *frame, const float co[3], const float radius[2], const float mat[3][3], float offset)
{
float rx[3], ry[3], rz[3];
int i;
@@ -814,9 +813,8 @@ static int calc_edge_subdivisions(const MVert *mvert,
if (v1_branch && v2_branch) {
return 2;
}
- else {
- return 0;
- }
+
+ return 0;
}
avg_radius = half_v2(evs[0]->radius) + half_v2(evs[1]->radius);
diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c
index 7e5e4ecd9d3..7a4c45b73bd 100644
--- a/source/blender/modifiers/intern/MOD_solidify_extrude.c
+++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c
@@ -182,7 +182,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, float (*poly_nors)[3], float (*r_ver
/* -------------------------------------------------------------------- */
/** \name Main Solidify Function
* \{ */
-
+/* NOLINTNEXTLINE: readability-function-size */
Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
Mesh *result;
diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
index 423a6b4458a..1e0269617ec 100644
--- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
+++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
@@ -132,6 +132,7 @@ static int comp_float_int_pair(const void *a, const void *b)
return (int)(x->angle > y->angle) - (int)(x->angle < y->angle);
}
+/* NOLINTNEXTLINE: readability-function-size */
Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const ModifierEvalContext *ctx,
Mesh *mesh)
@@ -479,12 +480,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
old_edge_vert_ref->edges_len++;
break;
}
- else if (vm[orig_medge[edge].v1] == vs[1 - j]) {
+ if (vm[orig_medge[edge].v1] == vs[1 - j]) {
invalid_edge_index = edge + 1;
invalid_edge_reversed = (j == 0);
break;
}
- else if (vm[orig_medge[edge].v2] == vs[1 - j]) {
+ if (vm[orig_medge[edge].v2] == vs[1 - j]) {
invalid_edge_index = edge + 1;
invalid_edge_reversed = (j == 1);
break;
@@ -936,7 +937,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
break;
}
- else if (edge->faces[0] == eg_track_faces[0]) {
+ if (edge->faces[0] == eg_track_faces[0]) {
insert_at_start = true;
eg_track_faces[0] = edge->faces[1];
found_edge = edge;
@@ -945,14 +946,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
}
break;
}
- else if (edge->faces[1] != NULL) {
+ if (edge->faces[1] != NULL) {
if (edge->faces[1] == eg_track_faces[1]) {
insert_at_start = false;
eg_track_faces[1] = edge->faces[0];
found_edge = edge;
break;
}
- else if (edge->faces[1] == eg_track_faces[0]) {
+ if (edge->faces[1] == eg_track_faces[0]) {
insert_at_start = true;
eg_track_faces[0] = edge->faces[0];
found_edge = edge;
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 6a0e82a686b..962e93be215 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -372,9 +372,8 @@ BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3
len_squared_v3v3(point_co, data->targetCos[edge->v2])) {
return edge->v1;
}
- else {
- return edge->v2;
- }
+
+ return edge->v2;
}
BLI_INLINE int isPolyValid(const float coords[][2], const uint nr)
@@ -450,7 +449,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data,
SDefBindWeightData *bwdata;
SDefBindPoly *bpoly;
- float world[3] = {0.0f, 0.0f, 1.0f};
+ const float world[3] = {0.0f, 0.0f, 1.0f};
float avg_point_dist = 0.0f;
float tot_weight = 0.0f;
int inf_weight_flags = 0;
@@ -1283,7 +1282,7 @@ static void surfacedeformModifier_do(ModifierData *md,
BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts);
return;
}
- else if (smd->numpoly != tnumpoly) {
+ if (smd->numpoly != tnumpoly) {
BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
return;
}
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index 01b9e972086..8de4b042eb3 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -179,12 +179,11 @@ static int modifier_is_simulation(ModifierData *md)
return 1;
}
/* Particle Tab */
- else if (md->type == eModifierType_ParticleSystem) {
+ if (md->type == eModifierType_ParticleSystem) {
return 2;
}
- else {
- return 0;
- }
+
+ return 0;
}
static bool modifier_can_delete(ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c
index c6dff375109..179996d5acf 100644
--- a/source/blender/modifiers/intern/MOD_util.c
+++ b/source/blender/modifiers/intern/MOD_util.c
@@ -143,10 +143,9 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
MEM_freeN(done);
return;
}
- else {
- /* if there are no UVs, default to local */
- texmapping = MOD_DISP_MAP_LOCAL;
- }
+
+ /* if there are no UVs, default to local */
+ texmapping = MOD_DISP_MAP_LOCAL;
}
MVert *mv = mesh->mvert;
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index 4aca3c28ed8..adc89f1b954 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -49,7 +49,9 @@
#include "MOD_ui_common.h"
#include "MOD_util.h"
-static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4])
+static void uv_warp_from_mat4_pair(float uv_dst[2],
+ const float uv_src[2],
+ const float warp_mat[4][4])
{
float tuv[3] = {0.0f};
@@ -185,7 +187,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
mul_m4_m4m4(warp_mat, mat_cent, warp_mat);
}
- int shuf_indices[4] = {axis_u, axis_v, -1, 3};
+ const int shuf_indices[4] = {axis_u, axis_v, -1, 3};
shuffle_m4(shuf_mat, shuf_indices);
mul_m4_m4m4(warp_mat, shuf_mat, warp_mat);
transpose_m4(shuf_mat);
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index cbe774e91da..45252fed031 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -123,9 +123,8 @@ static bool dependsOnTime(ModifierData *md)
if (wmd->texture) {
return BKE_texture_dependsOnTime(wmd->texture);
}
- else {
- return false;
- }
+
+ return false;
}
static void freeData(ModifierData *md)
@@ -236,7 +235,7 @@ static void warpModifier_do(WarpModifierData *wmd,
}
if (wmd->curfalloff) {
- BKE_curvemapping_initialize(wmd->curfalloff);
+ BKE_curvemapping_init(wmd->curfalloff);
}
invert_m4_m4(obinv, ob->obmat);
diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c
index 54d3aa46344..4ee1f9f669a 100644
--- a/source/blender/modifiers/intern/MOD_weightvg_util.c
+++ b/source/blender/modifiers/intern/MOD_weightvg_util.c
@@ -83,7 +83,7 @@ void weightvg_do_map(
}
if (cmap && falloff_type == MOD_WVG_MAPPING_CURVE) {
- BKE_curvemapping_initialize(cmap);
+ BKE_curvemapping_init(cmap);
}
/* Map each weight (vertex) to its new value, accordingly to the chosen mode. */
@@ -382,4 +382,4 @@ void weightvg_ui_common(const bContext *C, PointerRNA *ob_ptr, PointerRNA *ptr,
}
}
}
-} \ No newline at end of file
+}
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 8039856172a..6bb4f3dc1b5 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -72,7 +72,7 @@ static void initData(ModifierData *md)
wmd->default_weight = 0.0f;
wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0);
- BKE_curvemapping_initialize(wmd->cmap_curve);
+ BKE_curvemapping_init(wmd->cmap_curve);
wmd->rem_threshold = 0.01f;
wmd->add_threshold = 0.01f;
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index d1c618df68b..9821ead2340 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -95,16 +95,16 @@ static float mix_weight(float weight, float weight2, char mix_mode)
if (mix_mode == MOD_WVG_MIX_SET) {
return weight2;
}
- else if (mix_mode == MOD_WVG_MIX_ADD) {
+ if (mix_mode == MOD_WVG_MIX_ADD) {
return (weight + weight2);
}
- else if (mix_mode == MOD_WVG_MIX_SUB) {
+ if (mix_mode == MOD_WVG_MIX_SUB) {
return (weight - weight2);
}
- else if (mix_mode == MOD_WVG_MIX_MUL) {
+ if (mix_mode == MOD_WVG_MIX_MUL) {
return (weight * weight2);
}
- else if (mix_mode == MOD_WVG_MIX_DIV) {
+ if (mix_mode == MOD_WVG_MIX_DIV) {
/* Avoid dividing by zero (or really small values). */
if (weight2 < 0.0f && weight2 > -MOD_WVG_ZEROFLOOR) {
weight2 = -MOD_WVG_ZEROFLOOR;
@@ -114,15 +114,14 @@ static float mix_weight(float weight, float weight2, char mix_mode)
}
return (weight / weight2);
}
- else if (mix_mode == MOD_WVG_MIX_DIF) {
+ if (mix_mode == MOD_WVG_MIX_DIF) {
return (weight < weight2 ? weight2 - weight : weight - weight2);
}
- else if (mix_mode == MOD_WVG_MIX_AVG) {
+ if (mix_mode == MOD_WVG_MIX_AVG) {
return (weight + weight2) * 0.5f;
}
- else {
- return weight2;
- }
+
+ return weight2;
}
/**************************************
diff --git a/source/blender/modifiers/intern/MOD_weld.c b/source/blender/modifiers/intern/MOD_weld.c
index cf92da1b0e6..a89209f5dbb 100644
--- a/source/blender/modifiers/intern/MOD_weld.c
+++ b/source/blender/modifiers/intern/MOD_weld.c
@@ -1850,23 +1850,22 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
&iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer)) {
continue;
}
- else {
- if (wp->poly_dst != OUT_OF_CONTEXT) {
- continue;
- }
- while (weld_iter_loop_of_poly_next(&iter)) {
- customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur);
- uint v = vert_final[iter.v];
- uint e = edge_final[iter.e];
- r_ml->v = v;
- r_ml->e = e;
- r_ml++;
- loop_cur++;
- if (iter.type) {
- result->medge[e].flag &= ~ME_LOOSEEDGE;
- }
- BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0);
+
+ if (wp->poly_dst != OUT_OF_CONTEXT) {
+ continue;
+ }
+ while (weld_iter_loop_of_poly_next(&iter)) {
+ customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur);
+ uint v = vert_final[iter.v];
+ uint e = edge_final[iter.e];
+ r_ml->v = v;
+ r_ml->e = e;
+ r_ml++;
+ loop_cur++;
+ if (iter.type) {
+ result->medge[e].flag &= ~ME_LOOSEEDGE;
}
+ BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0);
}
}
@@ -1885,24 +1884,24 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
&iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer)) {
continue;
}
- else {
- if (wp->poly_dst != OUT_OF_CONTEXT) {
- continue;
- }
- while (weld_iter_loop_of_poly_next(&iter)) {
- customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur);
- uint v = vert_final[iter.v];
- uint e = edge_final[iter.e];
- r_ml->v = v;
- r_ml->e = e;
- r_ml++;
- loop_cur++;
- if (iter.type) {
- result->medge[e].flag &= ~ME_LOOSEEDGE;
- }
- BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0);
+
+ if (wp->poly_dst != OUT_OF_CONTEXT) {
+ continue;
+ }
+ while (weld_iter_loop_of_poly_next(&iter)) {
+ customdata_weld(&mesh->ldata, &result->ldata, group_buffer, iter.group_len, loop_cur);
+ uint v = vert_final[iter.v];
+ uint e = edge_final[iter.e];
+ r_ml->v = v;
+ r_ml->e = e;
+ r_ml++;
+ loop_cur++;
+ if (iter.type) {
+ result->medge[e].flag &= ~ME_LOOSEEDGE;
}
+ BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0);
}
+
r_mp->loopstart = loop_start;
r_mp->totloop = loop_cur - loop_start;
r_mp++;
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 80720f5206a..33b95d50cc0 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -136,6 +136,7 @@ set(SRC
function/nodes/node_fn_float_compare.cc
function/nodes/node_fn_group_instance_id.cc
function/nodes/node_fn_object_transforms.cc
+ function/nodes/node_fn_random_float.cc
function/nodes/node_fn_switch.cc
function/node_function_util.cc
@@ -160,7 +161,7 @@ set(SRC
shader/nodes/node_shader_bsdf_velvet.c
shader/nodes/node_shader_bump.c
shader/nodes/node_shader_camera.c
- shader/nodes/node_shader_clamp.c
+ shader/nodes/node_shader_clamp.cc
shader/nodes/node_shader_common.c
shader/nodes/node_shader_curves.c
shader/nodes/node_shader_displacement.c
@@ -232,10 +233,12 @@ set(SRC
shader/node_shader_tree.c
shader/node_shader_util.c
+ simulation/nodes/node_sim_age_reached_event.cc
simulation/nodes/node_sim_common.cc
simulation/nodes/node_sim_emit_particles.cc
simulation/nodes/node_sim_execute_condition.cc
simulation/nodes/node_sim_force.cc
+ simulation/nodes/node_sim_kill_particle.cc
simulation/nodes/node_sim_multi_execute.cc
simulation/nodes/node_sim_particle_attribute.cc
simulation/nodes/node_sim_particle_birth_event.cc
@@ -278,6 +281,7 @@ set(SRC
intern/node_common.c
intern/node_exec.c
intern/node_socket.cc
+ intern/node_tree_dependencies.cc
intern/node_tree_multi_function.cc
intern/node_tree_ref.cc
intern/node_util.c
@@ -292,6 +296,7 @@ set(SRC
NOD_composite.h
NOD_derived_node_tree.hh
NOD_function.h
+ NOD_node_tree_dependencies.hh
NOD_node_tree_multi_function.hh
NOD_node_tree_ref.hh
NOD_shader.h
diff --git a/source/blender/nodes/NOD_derived_node_tree.hh b/source/blender/nodes/NOD_derived_node_tree.hh
index 205ba68dd0a..570b6cb704d 100644
--- a/source/blender/nodes/NOD_derived_node_tree.hh
+++ b/source/blender/nodes/NOD_derived_node_tree.hh
@@ -171,7 +171,6 @@ using NodeTreeRefMap = Map<bNodeTree *, std::unique_ptr<const NodeTreeRef>>;
class DerivedNodeTree : NonCopyable, NonMovable {
private:
LinearAllocator<> allocator_;
- bNodeTree *btree_;
Vector<DNode *> nodes_by_id_;
Vector<DGroupInput *> group_inputs_;
Vector<DParentNode *> parent_nodes_;
@@ -180,7 +179,7 @@ class DerivedNodeTree : NonCopyable, NonMovable {
Vector<DInputSocket *> input_sockets_;
Vector<DOutputSocket *> output_sockets_;
- Map<const bNodeType *, Vector<DNode *>> nodes_by_type_;
+ MultiValueMap<const bNodeType *, DNode *> nodes_by_type_;
public:
DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs);
@@ -482,13 +481,7 @@ inline Span<const DNode *> DerivedNodeTree::nodes_by_type(StringRefNull idname)
inline Span<const DNode *> DerivedNodeTree::nodes_by_type(const bNodeType *nodetype) const
{
- const Vector<DNode *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return *nodes;
- }
+ return nodes_by_type_.lookup(nodetype);
}
inline Span<const DSocket *> DerivedNodeTree::sockets() const
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
index 5391951debb..58a968151ac 100644
--- a/source/blender/nodes/NOD_function.h
+++ b/source/blender/nodes/NOD_function.h
@@ -26,6 +26,7 @@ void register_node_type_fn_switch(void);
void register_node_type_fn_group_instance_id(void);
void register_node_type_fn_combine_strings(void);
void register_node_type_fn_object_transforms(void);
+void register_node_type_fn_random_float(void);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/NOD_node_tree_dependencies.hh b/source/blender/nodes/NOD_node_tree_dependencies.hh
new file mode 100644
index 00000000000..13bb2bde2f3
--- /dev/null
+++ b/source/blender/nodes/NOD_node_tree_dependencies.hh
@@ -0,0 +1,76 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "BLI_vector_set.hh"
+
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+
+struct bNodeTree;
+
+namespace blender::nodes {
+
+class NodeTreeDependencies {
+ private:
+ VectorSet<Object *> transform_deps_;
+ VectorSet<Object *> geometry_deps_;
+ VectorSet<ID *> id_deps_;
+
+ public:
+ void add_transform_dependency(Object *object)
+ {
+ if (object == nullptr) {
+ return;
+ }
+ transform_deps_.add(object);
+ id_deps_.add(&object->id);
+ }
+
+ void add_geometry_dependency(Object *object)
+ {
+ if (object == nullptr) {
+ return;
+ }
+ geometry_deps_.add(object);
+ id_deps_.add(&object->id);
+ }
+
+ bool depends_on(ID *id) const
+ {
+ return id_deps_.contains(id);
+ }
+
+ Span<Object *> transform_dependencies()
+ {
+ return transform_deps_;
+ }
+
+ Span<Object *> geometry_dependencies()
+ {
+ return geometry_deps_;
+ }
+
+ Span<ID *> id_dependencies()
+ {
+ return id_deps_;
+ }
+};
+
+NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree);
+
+} // namespace blender::nodes
diff --git a/source/blender/nodes/NOD_node_tree_multi_function.hh b/source/blender/nodes/NOD_node_tree_multi_function.hh
index f5cb827dc4f..cbd7a47f090 100644
--- a/source/blender/nodes/NOD_node_tree_multi_function.hh
+++ b/source/blender/nodes/NOD_node_tree_multi_function.hh
@@ -250,19 +250,17 @@ class MFNetworkBuilderBase {
*/
class SocketMFNetworkBuilder : public MFNetworkBuilderBase {
private:
- const DSocket *dsocket_ = nullptr;
- const DGroupInput *group_input_ = nullptr;
bNodeSocket *bsocket_;
fn::MFOutputSocket *built_socket_ = nullptr;
public:
SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DSocket &dsocket)
- : MFNetworkBuilderBase(common), dsocket_(&dsocket), bsocket_(dsocket.bsocket())
+ : MFNetworkBuilderBase(common), bsocket_(dsocket.bsocket())
{
}
SocketMFNetworkBuilder(CommonMFNetworkBuilderData &common, const DGroupInput &group_input)
- : MFNetworkBuilderBase(common), group_input_(&group_input), bsocket_(group_input.bsocket())
+ : MFNetworkBuilderBase(common), bsocket_(group_input.bsocket())
{
}
diff --git a/source/blender/nodes/NOD_node_tree_ref.hh b/source/blender/nodes/NOD_node_tree_ref.hh
index f18a20d6df9..6d1c239d2cb 100644
--- a/source/blender/nodes/NOD_node_tree_ref.hh
+++ b/source/blender/nodes/NOD_node_tree_ref.hh
@@ -46,6 +46,7 @@
#include "BLI_array.hh"
#include "BLI_linear_allocator.hh"
#include "BLI_map.hh"
+#include "BLI_multi_value_map.hh"
#include "BLI_string_ref.hh"
#include "BLI_timeit.hh"
#include "BLI_utility_mixins.hh"
@@ -161,7 +162,7 @@ class NodeTreeRef : NonCopyable, NonMovable {
Vector<SocketRef *> sockets_by_id_;
Vector<InputSocketRef *> input_sockets_;
Vector<OutputSocketRef *> output_sockets_;
- Map<const bNodeType *, Vector<NodeRef *>> nodes_by_type_;
+ MultiValueMap<const bNodeType *, NodeRef *> nodes_by_type_;
public:
NodeTreeRef(bNodeTree *btree);
@@ -410,13 +411,7 @@ inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(StringRefNull idname) co
inline Span<const NodeRef *> NodeTreeRef::nodes_by_type(const bNodeType *nodetype) const
{
- const Vector<NodeRef *> *nodes = nodes_by_type_.lookup_ptr(nodetype);
- if (nodes == nullptr) {
- return {};
- }
- else {
- return *nodes;
- }
+ return nodes_by_type_.lookup(nodetype);
}
inline Span<const SocketRef *> NodeTreeRef::sockets() const
diff --git a/source/blender/nodes/NOD_simulation.h b/source/blender/nodes/NOD_simulation.h
index d769bbce204..266ded997c6 100644
--- a/source/blender/nodes/NOD_simulation.h
+++ b/source/blender/nodes/NOD_simulation.h
@@ -38,6 +38,8 @@ void register_node_type_sim_particle_mesh_collision_event(void);
void register_node_type_sim_emit_particles(void);
void register_node_type_sim_time(void);
void register_node_type_sim_particle_attribute(void);
+void register_node_type_sim_age_reached_event(void);
+void register_node_type_sim_kill_particle(void);
#ifdef __cplusplus
}
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 31ce3f81450..7922a73902c 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -270,6 +270,8 @@ DefNode(SimulationNode, SIM_NODE_PARTICLE_MESH_COLLISION_EVENT, 0, "PARTIC
DefNode(SimulationNode, SIM_NODE_EMIT_PARTICLES, 0, "EMIT_PARTICLES", EmitParticles, "Emit Particles", "")
DefNode(SimulationNode, SIM_NODE_TIME, def_sim_time, "TIME", Time, "Time", "")
DefNode(SimulationNode, SIM_NODE_PARTICLE_ATTRIBUTE, def_sim_particle_attribute, "PARTICLE_ATTRIBUTE", ParticleAttribute, "Particle Attribute", "")
+DefNode(SimulationNode, SIM_NODE_AGE_REACHED_EVENT, 0, "AGE_REACHED_EVENT", AgeReachedEvent, "Age Reached Event", "")
+DefNode(SimulationNode, SIM_NODE_KILL_PARTICLE, 0, "KILL_PARTICLE", KillParticle, "Kill Particle", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", "")
@@ -277,7 +279,7 @@ DefNode(FunctionNode, FN_NODE_SWITCH, def_fn_switch, "SWITCH",
DefNode(FunctionNode, FN_NODE_GROUP_INSTANCE_ID, 0, "GROUP_INSTANCE_ID", GroupInstanceID, "Group Instance ID", "")
DefNode(FunctionNode, FN_NODE_COMBINE_STRINGS, 0, "COMBINE_STRINGS", CombineStrings, "Combine Strings", "")
DefNode(FunctionNode, FN_NODE_OBJECT_TRANSFORMS, 0, "OBJECT_TRANSFORMS", ObjectTransforms, "Object Transforms", "")
-
+DefNode(FunctionNode, FN_NODE_RANDOM_FLOAT, 0, "RANDOM_FLOAT", RandomFloat, "Random Float", "")
/* undefine macros */
diff --git a/source/blender/nodes/function/nodes/node_fn_random_float.cc b/source/blender/nodes/function/nodes/node_fn_random_float.cc
new file mode 100644
index 00000000000..2ee0830637a
--- /dev/null
+++ b/source/blender/nodes/function/nodes/node_fn_random_float.cc
@@ -0,0 +1,89 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.hh"
+
+#include "BLI_hash.h"
+
+static bNodeSocketTemplate fn_node_random_float_in[] = {
+ {SOCK_FLOAT, N_("Min"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_FLOAT, N_("Max"), 1.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE},
+ {SOCK_INT, N_("Seed")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_random_float_out[] = {
+ {SOCK_FLOAT, N_("Value")},
+ {-1, ""},
+};
+
+class RandomFloatFunction : public blender::fn::MultiFunction {
+ private:
+ uint32_t function_seed_;
+
+ public:
+ RandomFloatFunction(uint32_t function_seed) : function_seed_(function_seed)
+ {
+ blender::fn::MFSignatureBuilder signature = this->get_builder("Random float");
+ signature.single_input<float>("Min");
+ signature.single_input<float>("Max");
+ signature.single_input<int>("Seed");
+ signature.single_output<float>("Value");
+ }
+
+ void call(blender::IndexMask mask,
+ blender::fn::MFParams params,
+ blender::fn::MFContext UNUSED(context)) const override
+ {
+ blender::fn::VSpan<float> min_values = params.readonly_single_input<float>(0, "Min");
+ blender::fn::VSpan<float> max_values = params.readonly_single_input<float>(1, "Max");
+ blender::fn::VSpan<int> seeds = params.readonly_single_input<int>(2, "Seed");
+ blender::MutableSpan<float> values = params.uninitialized_single_output<float>(3, "Value");
+
+ for (int64_t i : mask) {
+ const float min_value = min_values[i];
+ const float max_value = max_values[i];
+ const int seed = seeds[i];
+ const float value = BLI_hash_int_01((uint32_t)seed ^ function_seed_);
+ values[i] = value * (max_value - min_value) + min_value;
+ }
+ }
+};
+
+static void fn_node_random_float_expand_in_mf_network(
+ blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ uint32_t function_seed = 1746872341u;
+ const blender::nodes::DNode &node = builder.dnode();
+ const blender::DefaultHash<blender::StringRefNull> hasher;
+ function_seed = 33 * function_seed + hasher(node.name());
+ for (const blender::nodes::DParentNode *parent = node.parent(); parent != nullptr;
+ parent = parent->parent()) {
+ function_seed = 33 * function_seed + hasher(parent->node_ref().name());
+ }
+
+ builder.construct_and_set_matching_fn<RandomFloatFunction>(function_seed);
+}
+
+void register_node_type_fn_random_float()
+{
+ static bNodeType ntype;
+
+ fn_node_type_base(&ntype, FN_NODE_RANDOM_FLOAT, "Random Float", 0, 0);
+ node_type_socket_templates(&ntype, fn_node_random_float_in, fn_node_random_float_out);
+ ntype.expand_in_mf_network = fn_node_random_float_expand_in_mf_network;
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc
index b7c78cb1499..bcef8c33a3b 100644
--- a/source/blender/nodes/intern/derived_node_tree.cc
+++ b/source/blender/nodes/intern/derived_node_tree.cc
@@ -28,7 +28,7 @@ static const NodeTreeRef &get_tree_ref(NodeTreeRefMap &node_tree_refs, bNodeTree
[&]() { return std::make_unique<NodeTreeRef>(btree); });
}
-DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs) : btree_(btree)
+DerivedNodeTree::DerivedNodeTree(bNodeTree *btree, NodeTreeRefMap &node_tree_refs)
{
const NodeTreeRef &main_tree_ref = get_tree_ref(node_tree_refs, btree);
@@ -321,7 +321,7 @@ BLI_NOINLINE void DerivedNodeTree::store_in_this_and_init_ids(
node->id_ = node_index;
const bNodeType *nodetype = node->node_ref_->bnode()->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
+ nodes_by_type_.add(nodetype, node);
for (DInputSocket *socket : node->inputs_) {
socket->id_ = sockets_by_id_.append_and_get_index(socket);
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index 439e41b963b..aa1f23163a0 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -84,13 +84,11 @@ bool node_group_poll_instance(bNode *node, bNodeTree *nodetree)
if (grouptree) {
return nodeGroupPoll(nodetree, grouptree);
}
- else {
- return true; /* without a linked node tree, group node is always ok */
- }
- }
- else {
- return false;
+
+ return true; /* without a linked node tree, group node is always ok */
}
+
+ return false;
}
int nodeGroupPoll(bNodeTree *nodetree, bNodeTree *grouptree)
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 04d86f5b44e..0dfae7424cb 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -634,10 +634,10 @@ static bNodeSocketType *make_socket_type_string()
class ObjectSocketMultiFunction : public blender::fn::MultiFunction {
private:
- const Object *object_;
+ Object *object_;
public:
- ObjectSocketMultiFunction(const Object *object) : object_(object)
+ ObjectSocketMultiFunction(Object *object) : object_(object)
{
blender::fn::MFSignatureBuilder signature = this->get_builder("Object Socket");
signature.depends_on_context();
@@ -679,7 +679,7 @@ static bNodeSocketType *make_socket_type_object()
return blender::fn::MFDataType::ForSingle<blender::bke::PersistentObjectHandle>();
};
socktype->expand_in_mf_network = [](blender::nodes::SocketMFNetworkBuilder &builder) {
- const Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
+ Object *object = builder.socket_default_value<bNodeSocketValueObject>()->value;
builder.construct_generator_fn<ObjectSocketMultiFunction>(object);
};
return socktype;
diff --git a/source/blender/nodes/intern/node_tree_dependencies.cc b/source/blender/nodes/intern/node_tree_dependencies.cc
new file mode 100644
index 00000000000..efe75a10f7e
--- /dev/null
+++ b/source/blender/nodes/intern/node_tree_dependencies.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "NOD_node_tree_dependencies.hh"
+
+#include "DNA_node_types.h"
+
+#include "BKE_node.h"
+
+namespace blender::nodes {
+
+static void add_dependencies_of_node_tree(bNodeTree &ntree, NodeTreeDependencies &r_dependencies)
+{
+ /* TODO: Do a bit more sophisticated parsing to see which dependencies are really required. */
+ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (socket->type == SOCK_OBJECT) {
+ Object *object = ((bNodeSocketValueObject *)socket->default_value)->value;
+ if (object != nullptr) {
+ r_dependencies.add_transform_dependency(object);
+ if (object->type == OB_MESH) {
+ r_dependencies.add_geometry_dependency(object);
+ }
+ }
+ }
+ }
+
+ if (node->type == NODE_GROUP) {
+ bNodeTree *group = (bNodeTree *)node->id;
+ if (group != nullptr) {
+ add_dependencies_of_node_tree(*group, r_dependencies);
+ }
+ }
+ }
+}
+
+NodeTreeDependencies find_node_tree_dependencies(bNodeTree &ntree)
+{
+ NodeTreeDependencies dependencies;
+ add_dependencies_of_node_tree(ntree, dependencies);
+ return dependencies;
+}
+
+} // namespace blender::nodes
diff --git a/source/blender/nodes/intern/node_tree_multi_function.cc b/source/blender/nodes/intern/node_tree_multi_function.cc
index 82842c4ef32..09a80fd23f4 100644
--- a/source/blender/nodes/intern/node_tree_multi_function.cc
+++ b/source/blender/nodes/intern/node_tree_multi_function.cc
@@ -176,13 +176,12 @@ static fn::MFOutputSocket *try_find_origin(CommonMFNetworkBuilderData &common,
}
return nullptr;
}
- else {
- const DGroupInput &from_group_input = *from_group_inputs[0];
- if (is_multi_function_data_socket(from_group_input.bsocket())) {
- return &common.network_map.lookup(from_group_input);
- }
- return nullptr;
+
+ const DGroupInput &from_group_input = *from_group_inputs[0];
+ if (is_multi_function_data_socket(from_group_input.bsocket())) {
+ return &common.network_map.lookup(from_group_input);
}
+ return nullptr;
}
using ImplicitConversionsMap =
diff --git a/source/blender/nodes/intern/node_tree_ref.cc b/source/blender/nodes/intern/node_tree_ref.cc
index 186ca750f10..47669bc5ca2 100644
--- a/source/blender/nodes/intern/node_tree_ref.cc
+++ b/source/blender/nodes/intern/node_tree_ref.cc
@@ -79,7 +79,7 @@ NodeTreeRef::NodeTreeRef(bNodeTree *btree) : btree_(btree)
for (NodeRef *node : nodes_by_id_) {
const bNodeType *nodetype = node->bnode_->typeinfo;
- nodes_by_type_.lookup_or_add_default(nodetype).append(node);
+ nodes_by_type_.add(nodetype, node);
}
}
diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c
index 9efbdc079e6..b2309abe32e 100644
--- a/source/blender/nodes/intern/node_util.c
+++ b/source/blender/nodes/intern/node_util.c
@@ -73,7 +73,7 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context),
bNode *node,
bNodeInstanceKey UNUSED(key))
{
- BKE_curvemapping_initialize(node->storage);
+ BKE_curvemapping_init(node->storage);
return NULL; /* unused return */
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c
index 6b5d46e250b..116bc181997 100644
--- a/source/blender/nodes/shader/nodes/node_shader_attribute.c
+++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c
@@ -55,17 +55,16 @@ static int node_shader_gpu_attribute(GPUMaterial *mat,
return 1;
}
- else {
- GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name);
- GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
- /* for each output. */
- for (int i = 0; sh_node_attribute_out[i].type != -1; i++) {
- node_shader_gpu_bump_tex_coord(mat, node, &out[i].link);
- }
+ GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name);
+ GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr);
- return 1;
+ /* for each output. */
+ for (int i = 0; sh_node_attribute_out[i].type != -1; i++) {
+ node_shader_gpu_bump_tex_coord(mat, node, &out[i].link);
}
+
+ return 1;
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.c b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
index 808f9686f0a..d3a893e1d76 100644
--- a/source/blender/nodes/shader/nodes/node_shader_clamp.c
+++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc
@@ -50,6 +50,29 @@ static int gpu_shader_clamp(GPUMaterial *mat,
GPU_stack_link(mat, node, "clamp_range", in, out);
}
+static void sh_node_clamp_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
+{
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> minmax_fn{
+ "Clamp (Min Max)",
+ [](float value, float min, float max) { return std::min(std::max(value, min), max); }};
+ static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, float> range_fn{
+ "Clamp (Range)", [](float value, float a, float b) {
+ if (a < b) {
+ return clamp_f(value, a, b);
+ }
+
+ return clamp_f(value, b, a);
+ }};
+
+ int clamp_type = builder.bnode().custom1;
+ if (clamp_type == NODE_CLAMP_MINMAX) {
+ builder.set_matching_fn(minmax_fn);
+ }
+ else {
+ builder.set_matching_fn(range_fn);
+ }
+}
+
void register_node_type_sh_clamp(void)
{
static bNodeType ntype;
@@ -58,6 +81,7 @@ void register_node_type_sh_clamp(void)
node_type_socket_templates(&ntype, sh_node_clamp_in, sh_node_clamp_out);
node_type_init(&ntype, node_shader_init_clamp);
node_type_gpu(&ntype, gpu_shader_clamp);
+ ntype.expand_in_mf_network = sh_node_clamp_expand_in_mf_network;
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index 68f252cb092..42299a193e2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -168,7 +168,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
CurveMapping *cumap = node->storage;
- BKE_curvemapping_initialize(cumap);
+ BKE_curvemapping_init(cumap);
BKE_curvemapping_table_RGBA(cumap, &array, &size);
GPUNodeLink *tex = GPU_color_band(mat, size, array, &layer);
@@ -215,20 +215,19 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
GPU_uniform(range_rgba),
GPU_uniform(ext_rgba[3]));
}
- else {
- return GPU_stack_link(mat,
- node,
- "curves_rgb",
- in,
- out,
- tex,
- GPU_constant(&layer),
- GPU_uniform(range_rgba),
- GPU_uniform(ext_rgba[0]),
- GPU_uniform(ext_rgba[1]),
- GPU_uniform(ext_rgba[2]),
- GPU_uniform(ext_rgba[3]));
- }
+
+ return GPU_stack_link(mat,
+ node,
+ "curves_rgb",
+ in,
+ out,
+ tex,
+ GPU_constant(&layer),
+ GPU_uniform(range_rgba),
+ GPU_uniform(ext_rgba[0]),
+ GPU_uniform(ext_rgba[1]),
+ GPU_uniform(ext_rgba[2]),
+ GPU_uniform(ext_rgba[3]));
}
void register_node_type_sh_curve_rgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_displacement.c b/source/blender/nodes/shader/nodes/node_shader_displacement.c
index 22fbe4e4da6..649aad370c0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_displacement.c
@@ -64,10 +64,9 @@ static int gpu_shader_displacement(GPUMaterial *mat,
return GPU_stack_link(
mat, node, "node_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
}
- else {
- return GPU_stack_link(
- mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
- }
+
+ return GPU_stack_link(
+ mat, node, "node_displacement_world", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_geometry.c b/source/blender/nodes/shader/nodes/node_shader_geometry.c
index deb0ee9037c..f66633e64c8 100644
--- a/source/blender/nodes/shader/nodes/node_shader_geometry.c
+++ b/source/blender/nodes/shader/nodes/node_shader_geometry.c
@@ -42,9 +42,12 @@ static int node_shader_gpu_geometry(GPUMaterial *mat,
{
/* HACK: Don't request GPU_BARYCENTRIC_TEXCO if not used because it will
* trigger the use of geometry shader (and the performance penalty it implies). */
- float val[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ const float val[4] = {0.0f, 0.0f, 0.0f, 0.0f};
GPUNodeLink *bary_link = (!out[5].hasoutput) ? GPU_constant(val) :
GPU_builtin(GPU_BARYCENTRIC_TEXCO);
+ if (out[5].hasoutput) {
+ GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC);
+ }
/* Opti: don't request orco if not needed. */
GPUNodeLink *orco_link = (!out[2].hasoutput) ? GPU_constant(val) :
GPU_attribute(mat, CD_ORCO, "");
diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c
index 6750acf5ee1..774e7fed029 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mapping.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c
@@ -53,9 +53,8 @@ static int gpu_shader_mapping(GPUMaterial *mat,
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
return GPU_stack_link(mat, node, names[node->custom1], in, out);
}
- else {
- return 0;
- }
+
+ return 0;
}
static void node_shader_update_mapping(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc
index c7035da8c70..e7bbadfbcb0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_math.cc
@@ -141,9 +141,8 @@ static int gpu_shader_math(GPUMaterial *mat,
}
return ret;
}
- else {
- return 0;
- }
+
+ return 0;
}
static const blender::fn::MultiFunction &get_base_multi_function(
diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
index 93e88664d1a..8725122b12c 100644
--- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
+++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c
@@ -91,16 +91,15 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat,
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
int ret = GPU_stack_link(mat, node, names[node->custom1], in, out);
if (ret && node->custom2 & SHD_MIXRGB_CLAMP) {
- float min[3] = {0.0f, 0.0f, 0.0f};
- float max[3] = {1.0f, 1.0f, 1.0f};
+ const float min[3] = {0.0f, 0.0f, 0.0f};
+ const float max[3] = {1.0f, 1.0f, 1.0f};
GPU_link(
mat, "clamp_color", out[0].link, GPU_constant(min), GPU_constant(max), &out[0].link);
}
return ret;
}
- else {
- return 0;
- }
+
+ return 0;
}
void register_node_type_sh_mix_rgb(void)
diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.c b/source/blender/nodes/shader/nodes/node_shader_tangent.c
index e8bedde0a62..2c12bf9bc01 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tangent.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tangent.c
@@ -45,28 +45,27 @@ static int node_shader_gpu_tangent(GPUMaterial *mat,
return GPU_stack_link(
mat, node, "node_tangentmap", in, out, GPU_attribute(mat, CD_TANGENT, attr->uv_map));
}
- else {
- GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, "");
- if (attr->axis == SHD_TANGENT_AXIS_X) {
- GPU_link(mat, "tangent_orco_x", orco, &orco);
- }
- else if (attr->axis == SHD_TANGENT_AXIS_Y) {
- GPU_link(mat, "tangent_orco_y", orco, &orco);
- }
- else {
- GPU_link(mat, "tangent_orco_z", orco, &orco);
- }
+ GPUNodeLink *orco = GPU_attribute(mat, CD_ORCO, "");
- return GPU_stack_link(mat,
- node,
- "node_tangent",
- in,
- out,
- GPU_builtin(GPU_WORLD_NORMAL),
- orco,
- GPU_builtin(GPU_OBJECT_MATRIX));
+ if (attr->axis == SHD_TANGENT_AXIS_X) {
+ GPU_link(mat, "tangent_orco_x", orco, &orco);
+ }
+ else if (attr->axis == SHD_TANGENT_AXIS_Y) {
+ GPU_link(mat, "tangent_orco_y", orco, &orco);
}
+ else {
+ GPU_link(mat, "tangent_orco_z", orco, &orco);
+ }
+
+ return GPU_stack_link(mat,
+ node,
+ "node_tangent",
+ in,
+ out,
+ GPU_builtin(GPU_WORLD_NORMAL),
+ orco,
+ GPU_builtin(GPU_OBJECT_MATRIX));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 0cf4b51f307..38e79ebe94d 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -19,8 +19,6 @@
#include "../node_shader_util.h"
-#include "GPU_draw.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_environment_in[] = {
@@ -59,7 +57,8 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat,
NodeTexImage *tex_original = node_original->storage;
ImageUser *iuser = &tex_original->iuser;
eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
- if (GPU_get_mipmap()) {
+ /* TODO(fclem) For now assume mipmap is always enabled. */
+ if (true) {
sampler |= GPU_SAMPLER_MIPMAP;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index cbda72cd228..1a78d2f5bf2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -19,8 +19,6 @@
#include "../node_shader_util.h"
-#include "GPU_draw.h"
-
/* **************** OUTPUT ******************** */
static bNodeSocketTemplate sh_node_tex_image_in[] = {
@@ -95,7 +93,8 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat,
if (tex->interpolation != SHD_INTERP_CLOSEST) {
sampler_state |= GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER;
- sampler_state |= GPU_get_mipmap() ? GPU_SAMPLER_MIPMAP : 0;
+ /* TODO(fclem) For now assume mipmap is always enabled. */
+ sampler_state |= true ? GPU_SAMPLER_MIPMAP : 0;
}
const bool use_cubic = ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
index 94ffbbe0c55..9ef05d781bd 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.c
@@ -170,7 +170,7 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPU_uniform(xyz_to_rgb.g),
GPU_uniform(xyz_to_rgb.b));
}
- else if (tex->sky_model == 1) {
+ if (tex->sky_model == 1) {
/* Hosek / Wilkie */
sun_angles[0] = fmin(M_PI_2, sun_angles[0]); /* clamp to horizon */
SKY_ArHosekSkyModelState *sky_state = SKY_arhosek_xyz_skymodelstate_alloc_init(
@@ -210,9 +210,8 @@ static int node_shader_gpu_tex_sky(GPUMaterial *mat,
GPU_uniform(xyz_to_rgb.g),
GPU_uniform(xyz_to_rgb.b));
}
- else {
- return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
- }
+
+ return GPU_stack_link(mat, node, "node_tex_sky_nishita", in, out);
}
static void node_shader_update_sky(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c
index 817ccdc8b6a..56ecb6d4476 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.c
@@ -54,9 +54,8 @@ static int gpu_shader_tex_white_noise(GPUMaterial *mat,
if (node->custom1 < ARRAY_SIZE(names) && names[node->custom1]) {
return GPU_stack_link(mat, node, names[node->custom1], in, out);
}
- else {
- return 0;
- }
+
+ return 0;
}
static void node_shader_update_tex_white_noise(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
index 7f712b0db40..7b4e568e923 100644
--- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.cc
@@ -121,9 +121,8 @@ static int gpu_shader_valtorgb(GPUMaterial *mat,
if (coba->ipotype == COLBAND_INTERP_CONSTANT) {
return GPU_stack_link(mat, node, "valtorgb_nearest", in, out, tex, GPU_constant(&layer));
}
- else {
- return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer));
- }
+
+ return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer));
}
class ColorBandFunction : public blender::fn::MultiFunction {
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
index c9f79293328..0e82f346529 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_displacement.c
@@ -55,13 +55,12 @@ static int gpu_shader_vector_displacement(GPUMaterial *mat,
GPU_builtin(GPU_OBJECT_MATRIX),
GPU_builtin(GPU_VIEW_MATRIX));
}
- else if (node->custom1 == SHD_SPACE_OBJECT) {
+ if (node->custom1 == SHD_SPACE_OBJECT) {
return GPU_stack_link(
mat, node, "node_vector_displacement_object", in, out, GPU_builtin(GPU_OBJECT_MATRIX));
}
- else {
- return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out);
- }
+
+ return GPU_stack_link(mat, node, "node_vector_displacement_world", in, out);
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
index c18ad8bb244..e8396c7cfc1 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc
@@ -103,9 +103,8 @@ static int gpu_shader_vector_math(GPUMaterial *mat,
if (name != nullptr) {
return GPU_stack_link(mat, node, name, in, out);
}
- else {
- return 0;
- }
+
+ return 0;
}
static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
index 46a6ff1f353..b2132c59cde 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.c
@@ -53,9 +53,8 @@ static int gpu_shader_vector_rotate(GPUMaterial *mat,
float invert = (node->custom2) ? -1.0 : 1.0;
return GPU_stack_link(mat, node, names[node->custom1], in, out, GPU_constant(&invert));
}
- else {
- return 0;
- }
+
+ return 0;
}
static void node_shader_update_vector_rotate(bNodeTree *UNUSED(ntree), bNode *node)
diff --git a/source/blender/nodes/shader/nodes/node_shader_wireframe.c b/source/blender/nodes/shader/nodes/node_shader_wireframe.c
index e1da1cd34e4..37e60ddb205 100644
--- a/source/blender/nodes/shader/nodes/node_shader_wireframe.c
+++ b/source/blender/nodes/shader/nodes/node_shader_wireframe.c
@@ -36,20 +36,20 @@ static int node_shader_gpu_wireframe(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
+ GPU_material_flag_set(mat, GPU_MATFLAG_BARYCENTRIC);
/* node->custom1 is use_pixel_size */
if (node->custom1) {
return GPU_stack_link(
mat, node, "node_wireframe_screenspace", in, out, GPU_builtin(GPU_BARYCENTRIC_TEXCO));
}
- else {
- return GPU_stack_link(mat,
- node,
- "node_wireframe",
- in,
- out,
- GPU_builtin(GPU_BARYCENTRIC_TEXCO),
- GPU_builtin(GPU_BARYCENTRIC_DIST));
- }
+
+ return GPU_stack_link(mat,
+ node,
+ "node_wireframe",
+ in,
+ out,
+ GPU_builtin(GPU_BARYCENTRIC_TEXCO),
+ GPU_builtin(GPU_BARYCENTRIC_DIST));
}
/* node type definition */
diff --git a/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc
new file mode 100644
index 00000000000..add8c4eba4d
--- /dev/null
+++ b/source/blender/nodes/simulation/nodes/node_sim_age_reached_event.cc
@@ -0,0 +1,38 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_simulation_util.h"
+
+static bNodeSocketTemplate sim_node_age_reached_event_in[] = {
+ {SOCK_FLOAT, N_("Age"), 3, 0, 0, 0, 0, 10000000},
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate sim_node_age_reached_event_out[] = {
+ {SOCK_EVENTS, N_("Event")},
+ {-1, ""},
+};
+
+void register_node_type_sim_age_reached_event()
+{
+ static bNodeType ntype;
+
+ sim_node_type_base(&ntype, SIM_NODE_AGE_REACHED_EVENT, "Age Reached Event", 0, 0);
+ node_type_socket_templates(
+ &ntype, sim_node_age_reached_event_in, sim_node_age_reached_event_out);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc
new file mode 100644
index 00000000000..793b40d9365
--- /dev/null
+++ b/source/blender/nodes/simulation/nodes/node_sim_kill_particle.cc
@@ -0,0 +1,36 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_simulation_util.h"
+
+static bNodeSocketTemplate sim_node_kill_particle_in[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+static bNodeSocketTemplate sim_node_kill_particle_out[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
+ {-1, ""},
+};
+
+void register_node_type_sim_kill_particle()
+{
+ static bNodeType ntype;
+
+ sim_node_type_base(&ntype, SIM_NODE_KILL_PARTICLE, "Kill Particle", 0, 0);
+ node_type_socket_templates(&ntype, sim_node_kill_particle_in, sim_node_kill_particle_out);
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
index 2de7be2d3eb..5e1a6c35d52 100644
--- a/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
+++ b/source/blender/nodes/simulation/nodes/node_sim_particle_mesh_emitter.cc
@@ -20,7 +20,8 @@
static bNodeSocketTemplate sim_node_particle_mesh_emitter_in[] = {
{SOCK_OBJECT, N_("Object")},
- {SOCK_FLOAT, N_("Rate"), 10.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_FLOAT, N_("Rate"), 100.0f, 0.0f, 0.0f, 0.0f, 0.0f, FLT_MAX},
+ {SOCK_CONTROL_FLOW, N_("Execute")},
{-1, ""},
};
diff --git a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
index 8696dbe340c..8f5c6818cb4 100644
--- a/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
+++ b/source/blender/nodes/simulation/nodes/node_sim_set_particle_attribute.cc
@@ -18,6 +18,7 @@
#include "node_simulation_util.h"
static bNodeSocketTemplate sim_node_set_particle_attribute_in[] = {
+ {SOCK_CONTROL_FLOW, N_("Execute")},
{SOCK_STRING, N_("Name")},
{SOCK_FLOAT, N_("Float"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
{SOCK_INT, N_("Int"), 0, 0, 0, 0, -10000, 10000},
@@ -38,7 +39,7 @@ static void sim_node_set_particle_attribute_update(bNodeTree *UNUSED(ntree), bNo
{
int index = 0;
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
- if (index >= 1) {
+ if (index >= 2) {
nodeSetSocketAvailability(sock, sock->type == node->custom1);
}
index++;
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index 1d7641753e0..981fc4e308a 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -145,14 +145,13 @@ void tex_output(bNode *node,
/* do not add a delegate if the node is muted */
return;
}
+
+ if (!out->data) {
+ /* Freed in tex_end_exec (node.c) */
+ dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
+ }
else {
- if (!out->data) {
- /* Freed in tex_end_exec (node.c) */
- dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
- }
- else {
- dg = out->data;
- }
+ dg = out->data;
}
dg->cdata = cdata;
diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.c b/source/blender/nodes/texture/nodes/node_texture_curves.c
index d42985ba041..70f7e731720 100644
--- a/source/blender/nodes/texture/nodes/node_texture_curves.c
+++ b/source/blender/nodes/texture/nodes/node_texture_curves.c
@@ -39,7 +39,7 @@ static void time_colorfn(
fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1);
}
- BKE_curvemapping_initialize(node->storage);
+ BKE_curvemapping_init(node->storage);
fac = BKE_curvemapping_evaluateF(node->storage, 0, fac);
out[0] = CLAMPIS(fac, 0.0f, 1.0f);
}
diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c
index 825f9d56147..06eb632378c 100644
--- a/source/blender/nodes/texture/nodes/node_texture_rotate.c
+++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c
@@ -38,7 +38,7 @@ static bNodeSocketTemplate outputs[] = {
{-1, ""},
};
-static void rotate(float new_co[3], float a, float ax[3], const float co[3])
+static void rotate(float new_co[3], float a, const float ax[3], const float co[3])
{
float para[3];
float perp[3];
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index da9b5d642ef..7bcf96116b9 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -82,23 +82,23 @@ bool BPY_execute_text(struct bContext *C,
bool BPY_execute_string_as_number(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
double *r_value);
bool BPY_execute_string_as_intptr(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
intptr_t *r_value);
bool BPY_execute_string_as_string_and_size(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value,
size_t *r_value_size);
bool BPY_execute_string_as_string(struct bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value);
bool BPY_execute_string_ex(struct bContext *C,
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 1eccfe06d15..cdbd4832159 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -250,11 +250,9 @@ static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject
if (BMO_opcode_from_opname(opname) != -1) {
return bpy_bmesh_op_CreatePyObject(opname);
}
- else {
- PyErr_Format(
- PyExc_AttributeError, "BMeshOpsModule: operator \"%.200s\" doesn't exist", opname);
- return NULL;
- }
+
+ PyErr_Format(PyExc_AttributeError, "BMeshOpsModule: operator \"%.200s\" doesn't exist", opname);
+ return NULL;
}
static PyObject *bpy_bmesh_ops_fakemod_dir(PyObject *UNUSED(self))
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index b1e5c1c761b..a387ba31c84 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -82,7 +82,7 @@ static int bpy_slot_from_py_elem_check(BPy_BMElem *value,
Py_TYPE(value)->tp_name);
return -1;
}
- else if (value->bm == NULL) {
+ if (value->bm == NULL) {
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" %.200s invalidated element",
opname,
@@ -90,7 +90,7 @@ static int bpy_slot_from_py_elem_check(BPy_BMElem *value,
descr);
return -1;
}
- else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
+ if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" %.200s invalidated element",
opname,
@@ -127,7 +127,7 @@ static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value,
descr);
return -1;
}
- else if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
+ if (value->bm != bm) { /* we may want to make this check optional by setting 'bm' to NULL */
PyErr_Format(PyExc_TypeError,
"%.200s: keyword \"%.200s\" %.200s, invalidated sequence",
opname,
@@ -135,7 +135,7 @@ static int bpy_slot_from_py_elemseq_check(BPy_BMGeneric *value,
descr);
return -1;
}
- else if ((htype_py & htype_bmo) == 0) {
+ if ((htype_py & htype_bmo) == 0) {
char str_bmo[32];
char str_py[32];
PyErr_Format(PyExc_TypeError,
@@ -175,9 +175,8 @@ static int bpy_slot_from_py(BMesh *bm,
Py_TYPE(value)->tp_name);
return -1;
}
- else {
- BMO_SLOT_AS_BOOL(slot) = param;
- }
+
+ BMO_SLOT_AS_BOOL(slot) = param;
break;
}
@@ -223,9 +222,8 @@ static int bpy_slot_from_py(BMesh *bm,
Py_TYPE(value)->tp_name);
return -1;
}
- else {
- BMO_SLOT_AS_INT(slot) = param;
- }
+
+ BMO_SLOT_AS_INT(slot) = param;
}
break;
}
@@ -239,9 +237,9 @@ static int bpy_slot_from_py(BMesh *bm,
Py_TYPE(value)->tp_name);
return -1;
}
- else {
- BMO_SLOT_AS_FLOAT(slot) = param;
- }
+
+ BMO_SLOT_AS_FLOAT(slot) = param;
+
break;
}
case BMO_OP_SLOT_MAT: {
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index fccdfe7fbdc..e39b5faf3c4 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -292,14 +292,13 @@ static int bpy_bmesh_select_mode_set(BPy_BMesh *self, PyObject *value)
-1) {
return -1;
}
- else if (flag == 0) {
+ if (flag == 0) {
PyErr_SetString(PyExc_TypeError, "bm.select_mode: cant assignt an empty value");
return -1;
}
- else {
- self->bm->selectmode = flag;
- return 0;
- }
+
+ self->bm->selectmode = flag;
+ return 0;
}
PyDoc_STRVAR(bpy_bmesh_select_history_doc,
@@ -338,9 +337,8 @@ static int bpy_bmvert_co_set(BPy_BMVert *self, PyObject *value)
if (mathutils_array_parse(self->v->co, 3, 3, value, "BMVert.co") != -1) {
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyDoc_STRVAR(
@@ -359,9 +357,8 @@ static int bpy_bmvert_normal_set(BPy_BMVert *self, PyObject *value)
if (mathutils_array_parse(self->v->no, 3, 3, value, "BMVert.normal") != -1) {
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyDoc_STRVAR(bpy_bmvert_is_manifold_doc,
@@ -453,9 +450,8 @@ static int bpy_bmface_normal_set(BPy_BMFace *self, PyObject *value)
if (mathutils_array_parse(self->f->no, 3, 3, value, "BMFace.normal") != -1) {
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyDoc_STRVAR(bpy_bmface_material_index_doc, "The face's material index.\n\n:type: int");
@@ -481,10 +477,9 @@ static int bpy_bmface_material_index_set(BPy_BMFace *self, PyObject *value)
PyErr_SetString(PyExc_ValueError, "material index outside of usable range (0 - 32766)");
return -1;
}
- else {
- self->f->mat_nr = (short)param;
- return 0;
- }
+
+ self->f->mat_nr = (short)param;
+ return 0;
}
/* Loop
@@ -586,9 +581,8 @@ static PyObject *bpy_bmfaceseq_active_get(BPy_BMElemSeq *self, void *UNUSED(clos
if (bm->act_face) {
return BPy_BMElem_CreatePyObject(bm, (BMHeader *)bm->act_face);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNUSED(closure))
@@ -598,18 +592,17 @@ static int bpy_bmfaceseq_active_set(BPy_BMElem *self, PyObject *value, void *UNU
bm->act_face = NULL;
return 0;
}
- else if (BPy_BMFace_Check(value)) {
+ if (BPy_BMFace_Check(value)) {
BPY_BM_CHECK_SOURCE_INT(bm, "faces.active = f", value);
bm->act_face = ((BPy_BMFace *)value)->f;
return 0;
}
- else {
- PyErr_Format(PyExc_TypeError,
- "faces.active = f: expected BMFace or None, not %.200s",
- Py_TYPE(value)->tp_name);
- return -1;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "faces.active = f: expected BMFace or None, not %.200s",
+ Py_TYPE(value)->tp_name);
+ return -1;
}
static PyGetSetDef bpy_bmesh_getseters[] = {
@@ -971,10 +964,9 @@ static PyObject *bpy_bmesh_copy(BPy_BMesh *self)
if (bm_copy) {
return BPy_BMesh_CreatePyObject(bm_copy, BPY_BMFLAG_NOP);
}
- else {
- PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_SystemError, "Unable to copy BMesh, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bmesh_clear_doc,
@@ -1141,9 +1133,8 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
"evaluation mode is RENDER");
return NULL;
}
- else {
- me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks);
- }
+
+ me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &data_masks);
}
else {
if (use_cage) {
@@ -1161,7 +1152,7 @@ static PyObject *bpy_bmesh_from_object(BPy_BMesh *self, PyObject *args, PyObject
"from_object(...): cage arg is unsupported when deform=False");
return NULL;
}
- else if (use_render) {
+ if (use_render) {
me_eval = mesh_create_eval_no_deform_render(depsgraph, scene_eval, ob, &data_masks);
}
else {
@@ -1329,38 +1320,36 @@ static PyObject *bpy_bmesh_transform(BPy_BMElem *self, PyObject *args, PyObject
&filter)) {
return NULL;
}
- else {
- BMVert *eve;
- BMIter iter;
- void *mat_ptr;
- if (BaseMath_ReadCallback(mat) == -1) {
- return NULL;
- }
- else if (mat->num_col != 4 || mat->num_row != 4) {
- PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix");
- return NULL;
- }
+ BMVert *eve;
+ BMIter iter;
+ void *mat_ptr;
- if (filter != NULL &&
- PyC_FlagSet_ToBitfield(bpy_bm_hflag_all_flags, filter, &filter_flags, "bm.transform") ==
- -1) {
- return NULL;
- }
+ if (BaseMath_ReadCallback(mat) == -1) {
+ return NULL;
+ }
+ if (mat->num_col != 4 || mat->num_row != 4) {
+ PyErr_SetString(PyExc_ValueError, "expected a 4x4 matrix");
+ return NULL;
+ }
- mat_ptr = mat->matrix;
+ if (filter != NULL && PyC_FlagSet_ToBitfield(
+ bpy_bm_hflag_all_flags, filter, &filter_flags, "bm.transform") == -1) {
+ return NULL;
+ }
- if (!filter_flags) {
- BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
- mul_m4_v3((float(*)[4])mat_ptr, eve->co);
- }
+ mat_ptr = mat->matrix;
+
+ if (!filter_flags) {
+ BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
+ mul_m4_v3((float(*)[4])mat_ptr, eve->co);
}
- else {
- char filter_flags_ch = (char)filter_flags;
- BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(eve, filter_flags_ch)) {
- mul_m4_v3((float(*)[4])mat_ptr, eve->co);
- }
+ }
+ else {
+ char filter_flags_ch = (char)filter_flags;
+ BM_ITER_MESH (eve, &iter, self->bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(eve, filter_flags_ch)) {
+ mul_m4_v3((float(*)[4])mat_ptr, eve->co);
}
}
}
@@ -1388,9 +1377,8 @@ static PyObject *bpy_bmesh_calc_volume(BPy_BMElem *self, PyObject *args, PyObjec
args, kw, "|O!:calc_volume", (char **)kwlist, &PyBool_Type, &is_signed)) {
return NULL;
}
- else {
- return PyFloat_FromDouble(BM_mesh_calc_volume(self->bm, is_signed != Py_False));
- }
+
+ return PyFloat_FromDouble(BM_mesh_calc_volume(self->bm, is_signed != Py_False));
}
PyDoc_STRVAR(bpy_bmesh_calc_loop_triangles_doc,
@@ -1531,30 +1519,29 @@ static PyObject *bpy_bmvert_copy_from_vert_interp(BPy_BMVert *self, PyObject *ar
if (!PyArg_ParseTuple(args, "Of:BMVert.copy_from_vert_interp", &vert_seq, &fac)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BMVert **vert_array = NULL;
- Py_ssize_t vert_seq_len; /* always 2 */
-
- vert_array = BPy_BMElem_PySeq_As_Array(&bm,
- vert_seq,
- 2,
- 2,
- &vert_seq_len,
- BM_VERT,
- true,
- true,
- "BMVert.copy_from_vert_interp(...)");
-
- if (vert_array == NULL) {
- return NULL;
- }
-
- BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, clamp_f(fac, 0.0f, 1.0f));
- PyMem_FREE(vert_array);
- Py_RETURN_NONE;
+ BMesh *bm = self->bm;
+ BMVert **vert_array = NULL;
+ Py_ssize_t vert_seq_len; /* always 2 */
+
+ vert_array = BPy_BMElem_PySeq_As_Array(&bm,
+ vert_seq,
+ 2,
+ 2,
+ &vert_seq_len,
+ BM_VERT,
+ true,
+ true,
+ "BMVert.copy_from_vert_interp(...)");
+
+ if (vert_array == NULL) {
+ return NULL;
}
+
+ BM_data_interp_from_verts(bm, vert_array[0], vert_array[1], self->v, clamp_f(fac, 0.0f, 1.0f));
+
+ PyMem_FREE(vert_array);
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmvert_copy_from_face_interp_doc,
@@ -1574,15 +1561,14 @@ static PyObject *bpy_bmvert_copy_from_face_interp(BPy_BMVert *self, PyObject *ar
if (!PyArg_ParseTuple(args, "O!:BMVert.copy_from_face_interp", &BPy_BMFace_Type, &py_face)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "copy_from_face_interp()", py_face);
+ BMesh *bm = self->bm;
- BM_vert_interp_from_face(bm, self->v, py_face->f);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "copy_from_face_interp()", py_face);
- Py_RETURN_NONE;
- }
+ BM_vert_interp_from_face(bm, self->v, py_face->f);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmvert_calc_edge_angle_doc,
@@ -1615,12 +1601,11 @@ static PyObject *bpy_bmvert_calc_edge_angle(BPy_BMVert *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "BMVert.calc_edge_angle(): "
- "vert must connect to exactly 2 edges");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "BMVert.calc_edge_angle(): "
+ "vert must connect to exactly 2 edges");
+ return NULL;
}
return PyFloat_FromDouble(angle);
@@ -1697,12 +1682,11 @@ static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "BMEdge.calc_face_angle(): "
- "edge doesn't use 2 faces");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "BMEdge.calc_face_angle(): "
+ "edge doesn't use 2 faces");
+ return NULL;
}
return PyFloat_FromDouble(angle);
@@ -1737,12 +1721,11 @@ static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self, PyObject *a
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "BMEdge.calc_face_angle_signed(): "
- "edge doesn't use 2 faces");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "BMEdge.calc_face_angle_signed(): "
+ "edge doesn't use 2 faces");
+ return NULL;
}
return PyFloat_FromDouble(angle);
@@ -1767,13 +1750,12 @@ static PyObject *bpy_bmedge_calc_tangent(BPy_BMEdge *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O!:BMEdge.calc_face_tangent", &BPy_BMLoop_Type, &py_loop)) {
return NULL;
}
- else {
- float vec[3];
- BPY_BM_CHECK_OBJ(py_loop);
- /* no need to check if they are from the same mesh or even connected */
- BM_edge_calc_face_tangent(self->e, py_loop->l, vec);
- return Vector_CreatePyObject(vec, 3, NULL);
- }
+
+ float vec[3];
+ BPY_BM_CHECK_OBJ(py_loop);
+ /* no need to check if they are from the same mesh or even connected */
+ BM_edge_calc_face_tangent(self->e, py_loop->l, vec);
+ return Vector_CreatePyObject(vec, 3, NULL);
}
PyDoc_STRVAR(
@@ -1805,10 +1787,9 @@ static PyObject *bpy_bmedge_other_vert(BPy_BMEdge *self, BPy_BMVert *value)
if (other) {
return BPy_BMVert_CreatePyObject(self->bm, other);
}
- else {
- /* could raise an exception here */
- Py_RETURN_NONE;
- }
+
+ /* could raise an exception here */
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmedge_normal_update_doc,
@@ -1852,15 +1833,14 @@ static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *ar
&do_vertex)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "BMFace.copy_from_face_interp(face)", py_face);
+ BMesh *bm = self->bm;
- BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "BMFace.copy_from_face_interp(face)", py_face);
- Py_RETURN_NONE;
- }
+ BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmface_copy_doc,
@@ -1901,11 +1881,9 @@ static PyObject *bpy_bmface_copy(BPy_BMFace *self, PyObject *args, PyObject *kw)
if (f_cpy) {
return BPy_BMFace_CreatePyObject(bm, f_cpy);
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "BMFace.copy(): couldn't create the new face, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError, "BMFace.copy(): couldn't create the new face, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bmface_calc_area_doc,
@@ -2109,15 +2087,14 @@ static PyObject *bpy_bmloop_copy_from_face_interp(BPy_BMLoop *self, PyObject *ar
&do_multires)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "BMLoop.copy_from_face_interp(face)", py_face);
+ BMesh *bm = self->bm;
- BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "BMLoop.copy_from_face_interp(face)", py_face);
- Py_RETURN_NONE;
- }
+ BM_loop_interp_from_face(bm, self->l, py_face->f, do_vertex, do_multires);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmloop_calc_angle_doc,
@@ -2190,33 +2167,32 @@ static PyObject *bpy_bmvertseq_new(BPy_BMElemSeq *self, PyObject *args)
if (!PyArg_ParseTuple(args, "|OO!:verts.new", &py_co, &BPy_BMVert_Type, &py_vert_example)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BMVert *v;
- float co[3] = {0.0f, 0.0f, 0.0f};
- if (py_vert_example) {
- BPY_BM_CHECK_OBJ(py_vert_example);
- }
+ BMesh *bm = self->bm;
+ BMVert *v;
+ float co[3] = {0.0f, 0.0f, 0.0f};
- if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) {
- return NULL;
- }
+ if (py_vert_example) {
+ BPY_BM_CHECK_OBJ(py_vert_example);
+ }
- v = BM_vert_create(bm, co, NULL, BM_CREATE_NOP);
+ if (py_co && mathutils_array_parse(co, 3, 3, py_co, "verts.new(co)") == -1) {
+ return NULL;
+ }
- if (v == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "faces.new(verts): couldn't create the new face, internal error");
- return NULL;
- }
+ v = BM_vert_create(bm, co, NULL, BM_CREATE_NOP);
- if (py_vert_example) {
- BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v);
- }
+ if (v == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "faces.new(verts): couldn't create the new face, internal error");
+ return NULL;
+ }
- return BPy_BMVert_CreatePyObject(bm, v);
+ if (py_vert_example) {
+ BM_elem_attrs_copy(py_vert_example->bm, bm, py_vert_example->v, v);
}
+
+ return BPy_BMVert_CreatePyObject(bm, v);
}
/* Edge Seq
@@ -2242,49 +2218,48 @@ static PyObject *bpy_bmedgeseq_new(BPy_BMElemSeq *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O!:edges.new", &vert_seq, &BPy_BMEdge_Type, &py_edge_example)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BMEdge *e;
- BMVert **vert_array = NULL;
- Py_ssize_t vert_seq_len; /* always 2 */
- PyObject *ret = NULL;
- if (py_edge_example) {
- BPY_BM_CHECK_OBJ(py_edge_example);
- }
+ BMesh *bm = self->bm;
+ BMEdge *e;
+ BMVert **vert_array = NULL;
+ Py_ssize_t vert_seq_len; /* always 2 */
+ PyObject *ret = NULL;
- vert_array = BPy_BMElem_PySeq_As_Array(
- &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.new(...)");
+ if (py_edge_example) {
+ BPY_BM_CHECK_OBJ(py_edge_example);
+ }
- if (vert_array == NULL) {
- return NULL;
- }
+ vert_array = BPy_BMElem_PySeq_As_Array(
+ &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.new(...)");
- if (BM_edge_exists(vert_array[0], vert_array[1])) {
- PyErr_SetString(PyExc_ValueError, "edges.new(): this edge exists");
- goto cleanup;
- }
+ if (vert_array == NULL) {
+ return NULL;
+ }
- e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, BM_CREATE_NOP);
+ if (BM_edge_exists(vert_array[0], vert_array[1])) {
+ PyErr_SetString(PyExc_ValueError, "edges.new(): this edge exists");
+ goto cleanup;
+ }
- if (e == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "faces.new(verts): couldn't create the new face, internal error");
- goto cleanup;
- }
+ e = BM_edge_create(bm, vert_array[0], vert_array[1], NULL, BM_CREATE_NOP);
- if (py_edge_example) {
- BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e);
- }
+ if (e == NULL) {
+ PyErr_SetString(PyExc_ValueError,
+ "faces.new(verts): couldn't create the new face, internal error");
+ goto cleanup;
+ }
- ret = BPy_BMEdge_CreatePyObject(bm, e);
+ if (py_edge_example) {
+ BM_elem_attrs_copy(py_edge_example->bm, bm, py_edge_example->e, e);
+ }
- cleanup:
- if (vert_array) {
- PyMem_FREE(vert_array);
- }
- return ret;
+ ret = BPy_BMEdge_CreatePyObject(bm, e);
+
+cleanup:
+ if (vert_array) {
+ PyMem_FREE(vert_array);
}
+ return ret;
}
/* Face Seq
@@ -2310,58 +2285,57 @@ static PyObject *bpy_bmfaceseq_new(BPy_BMElemSeq *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O!:faces.new", &vert_seq, &BPy_BMFace_Type, &py_face_example)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- Py_ssize_t vert_seq_len;
- BMVert **vert_array = NULL;
+ BMesh *bm = self->bm;
+ Py_ssize_t vert_seq_len;
- PyObject *ret = NULL;
+ BMVert **vert_array = NULL;
- BMFace *f_new;
+ PyObject *ret = NULL;
- if (py_face_example) {
- BPY_BM_CHECK_OBJ(py_face_example);
- }
+ BMFace *f_new;
- vert_array = BPy_BMElem_PySeq_As_Array(
- &bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.new(...)");
+ if (py_face_example) {
+ BPY_BM_CHECK_OBJ(py_face_example);
+ }
- if (vert_array == NULL) {
- return NULL;
- }
+ vert_array = BPy_BMElem_PySeq_As_Array(
+ &bm, vert_seq, 3, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.new(...)");
- /* check if the face exists */
- if (BM_face_exists(vert_array, vert_seq_len) != NULL) {
- PyErr_SetString(PyExc_ValueError, "faces.new(verts): face already exists");
- goto cleanup;
- }
+ if (vert_array == NULL) {
+ return NULL;
+ }
- /* Go ahead and make the face!
- * --------------------------- */
+ /* check if the face exists */
+ if (BM_face_exists(vert_array, vert_seq_len) != NULL) {
+ PyErr_SetString(PyExc_ValueError, "faces.new(verts): face already exists");
+ goto cleanup;
+ }
- f_new = BM_face_create_verts(bm,
- vert_array,
- vert_seq_len,
- py_face_example ? py_face_example->f : NULL,
- BM_CREATE_NOP,
- true);
+ /* Go ahead and make the face!
+ * --------------------------- */
- if (UNLIKELY(f_new == NULL)) {
- PyErr_SetString(PyExc_ValueError,
- "faces.new(verts): couldn't create the new face, internal error");
- goto cleanup;
- }
+ f_new = BM_face_create_verts(bm,
+ vert_array,
+ vert_seq_len,
+ py_face_example ? py_face_example->f : NULL,
+ BM_CREATE_NOP,
+ true);
- ret = BPy_BMFace_CreatePyObject(bm, f_new);
+ if (UNLIKELY(f_new == NULL)) {
+ PyErr_SetString(PyExc_ValueError,
+ "faces.new(verts): couldn't create the new face, internal error");
+ goto cleanup;
+ }
- /* pass through */
- cleanup:
- if (vert_array) {
- PyMem_FREE(vert_array);
- }
- return ret;
+ ret = BPy_BMFace_CreatePyObject(bm, f_new);
+
+ /* pass through */
+cleanup:
+ if (vert_array) {
+ PyMem_FREE(vert_array);
}
+ return ret;
}
/* Elem Seq
@@ -2378,16 +2352,15 @@ static PyObject *bpy_bmvertseq_remove(BPy_BMElemSeq *self, BPy_BMVert *value)
if (!BPy_BMVert_Check(value)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "verts.remove(vert)", value);
+ BMesh *bm = self->bm;
- BM_vert_kill(bm, value->v);
- bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "verts.remove(vert)", value);
- Py_RETURN_NONE;
- }
+ BM_vert_kill(bm, value->v);
+ bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmedgeseq_remove_doc,
@@ -2401,16 +2374,15 @@ static PyObject *bpy_bmedgeseq_remove(BPy_BMElemSeq *self, BPy_BMEdge *value)
if (!BPy_BMEdge_Check(value)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "edges.remove(edges)", value);
+ BMesh *bm = self->bm;
- BM_edge_kill(bm, value->e);
- bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "edges.remove(edges)", value);
- Py_RETURN_NONE;
- }
+ BM_edge_kill(bm, value->e);
+ bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmfaceseq_remove_doc,
@@ -2424,16 +2396,15 @@ static PyObject *bpy_bmfaceseq_remove(BPy_BMElemSeq *self, BPy_BMFace *value)
if (!BPy_BMFace_Check(value)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BPY_BM_CHECK_SOURCE_OBJ(bm, "faces.remove(face)", value);
+ BMesh *bm = self->bm;
- BM_face_kill(bm, value->f);
- bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+ BPY_BM_CHECK_SOURCE_OBJ(bm, "faces.remove(face)", value);
- Py_RETURN_NONE;
- }
+ BM_face_kill(bm, value->f);
+ bpy_bm_generic_invalidate((BPy_BMGeneric *)value);
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bmedgeseq_get__method_doc,
@@ -2456,31 +2427,30 @@ static PyObject *bpy_bmedgeseq_get__method(BPy_BMElemSeq *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O:edges.get", &vert_seq, &fallback)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BMEdge *e;
- BMVert **vert_array = NULL;
- Py_ssize_t vert_seq_len; /* always 2 */
- PyObject *ret = NULL;
- vert_array = BPy_BMElem_PySeq_As_Array(
- &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.get(...)");
+ BMesh *bm = self->bm;
+ BMEdge *e;
+ BMVert **vert_array = NULL;
+ Py_ssize_t vert_seq_len; /* always 2 */
+ PyObject *ret = NULL;
- if (vert_array == NULL) {
- return NULL;
- }
+ vert_array = BPy_BMElem_PySeq_As_Array(
+ &bm, vert_seq, 2, 2, &vert_seq_len, BM_VERT, true, true, "edges.get(...)");
- if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) {
- ret = BPy_BMEdge_CreatePyObject(bm, e);
- }
- else {
- ret = fallback;
- Py_INCREF(ret);
- }
+ if (vert_array == NULL) {
+ return NULL;
+ }
- PyMem_FREE(vert_array);
- return ret;
+ if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) {
+ ret = BPy_BMEdge_CreatePyObject(bm, e);
+ }
+ else {
+ ret = fallback;
+ Py_INCREF(ret);
}
+
+ PyMem_FREE(vert_array);
+ return ret;
}
PyDoc_STRVAR(bpy_bmfaceseq_get__method_doc,
@@ -2503,32 +2473,31 @@ static PyObject *bpy_bmfaceseq_get__method(BPy_BMElemSeq *self, PyObject *args)
if (!PyArg_ParseTuple(args, "O|O:faces.get", &vert_seq, &fallback)) {
return NULL;
}
- else {
- BMesh *bm = self->bm;
- BMFace *f = NULL;
- BMVert **vert_array = NULL;
- Py_ssize_t vert_seq_len;
- PyObject *ret = NULL;
- vert_array = BPy_BMElem_PySeq_As_Array(
- &bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.get(...)");
+ BMesh *bm = self->bm;
+ BMFace *f = NULL;
+ BMVert **vert_array = NULL;
+ Py_ssize_t vert_seq_len;
+ PyObject *ret = NULL;
- if (vert_array == NULL) {
- return NULL;
- }
+ vert_array = BPy_BMElem_PySeq_As_Array(
+ &bm, vert_seq, 1, PY_SSIZE_T_MAX, &vert_seq_len, BM_VERT, true, true, "faces.get(...)");
- f = BM_face_exists(vert_array, vert_seq_len);
- if (f != NULL) {
- ret = BPy_BMFace_CreatePyObject(bm, f);
- }
- else {
- ret = fallback;
- Py_INCREF(ret);
- }
+ if (vert_array == NULL) {
+ return NULL;
+ }
- PyMem_FREE(vert_array);
- return ret;
+ f = BM_face_exists(vert_array, vert_seq_len);
+ if (f != NULL) {
+ ret = BPy_BMFace_CreatePyObject(bm, f);
}
+ else {
+ ret = fallback;
+ Py_INCREF(ret);
+ }
+
+ PyMem_FREE(vert_array);
+ return ret;
}
PyDoc_STRVAR(
@@ -2651,12 +2620,11 @@ static int bpy_bmelemseq_sort_cmp_by_keys_ascending(const void *index1_v,
if (keys[*index1] < keys[*index2]) {
return -1;
}
- else if (keys[*index1] > keys[*index2]) {
+ if (keys[*index1] > keys[*index2]) {
return 1;
}
- else {
- return 0;
- }
+
+ return 0;
}
static int bpy_bmelemseq_sort_cmp_by_keys_descending(const void *index1_v,
@@ -3260,54 +3228,51 @@ static PyObject *bpy_bmelemseq_subscript(BPy_BMElemSeq *self, PyObject *key)
}
return bpy_bmelemseq_subscript_int(self, i);
}
- else if (PySlice_Check(key)) {
+ if (PySlice_Check(key)) {
PySliceObject *key_slice = (PySliceObject *)key;
Py_ssize_t step = 1;
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
- else if (step != 1) {
+ if (step != 1) {
PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
return NULL;
}
- else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+ if (key_slice->start == Py_None && key_slice->stop == Py_None) {
return bpy_bmelemseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
- else {
- Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
- if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
- return NULL;
- }
- if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
- return NULL;
- }
+ Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- if (start < 0 || stop < 0) {
- /* only get the length for negative values */
- Py_ssize_t len = bpy_bmelemseq_length(self);
- if (start < 0) {
- start += len;
- }
- if (stop < 0) {
- stop += len;
- }
- }
+ /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
+ return NULL;
+ }
+ if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
+ return NULL;
+ }
- if (stop - start <= 0) {
- return PyList_New(0);
+ if (start < 0 || stop < 0) {
+ /* only get the length for negative values */
+ Py_ssize_t len = bpy_bmelemseq_length(self);
+ if (start < 0) {
+ start += len;
}
- else {
- return bpy_bmelemseq_subscript_slice(self, start, stop);
+ if (stop < 0) {
+ stop += len;
}
}
+
+ if (stop - start <= 0) {
+ return PyList_New(0);
+ }
+
+ return bpy_bmelemseq_subscript_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
+ return NULL;
}
static int bpy_bmelemseq_contains(BPy_BMElemSeq *self, PyObject *value)
@@ -3395,9 +3360,8 @@ static PyObject *bpy_bmiter_next(BPy_BMIter *self)
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
- else {
- return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele);
- }
+
+ return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, ele);
}
/* Dealloc Functions
@@ -3532,9 +3496,8 @@ static PyObject *bpy_bmesh_repr(BPy_BMesh *self)
bm->totface,
bm->totloop);
}
- else {
- return PyUnicode_FromFormat("<BMesh dead at %p>", self);
- }
+
+ return PyUnicode_FromFormat("<BMesh dead at %p>", self);
}
static PyObject *bpy_bmvert_repr(BPy_BMVert *self)
@@ -3545,9 +3508,8 @@ static PyObject *bpy_bmvert_repr(BPy_BMVert *self)
BMVert *v = self->v;
return PyUnicode_FromFormat("<BMVert(%p), index=%d>", v, BM_elem_index_get(v));
}
- else {
- return PyUnicode_FromFormat("<BMVert dead at %p>", self);
- }
+
+ return PyUnicode_FromFormat("<BMVert dead at %p>", self);
}
static PyObject *bpy_bmedge_repr(BPy_BMEdge *self)
@@ -3564,9 +3526,8 @@ static PyObject *bpy_bmedge_repr(BPy_BMEdge *self)
e->v2,
BM_elem_index_get(e->v2));
}
- else {
- return PyUnicode_FromFormat("<BMEdge dead at %p>", self);
- }
+
+ return PyUnicode_FromFormat("<BMEdge dead at %p>", self);
}
static PyObject *bpy_bmface_repr(BPy_BMFace *self)
@@ -3578,9 +3539,8 @@ static PyObject *bpy_bmface_repr(BPy_BMFace *self)
return PyUnicode_FromFormat(
"<BMFace(%p), index=%d, totverts=%d>", f, BM_elem_index_get(f), f->len);
}
- else {
- return PyUnicode_FromFormat("<BMFace dead at %p>", self);
- }
+
+ return PyUnicode_FromFormat("<BMFace dead at %p>", self);
}
static PyObject *bpy_bmloop_repr(BPy_BMLoop *self)
@@ -3599,9 +3559,8 @@ static PyObject *bpy_bmloop_repr(BPy_BMLoop *self)
l->f,
BM_elem_index_get(l->f));
}
- else {
- return PyUnicode_FromFormat("<BMLoop dead at %p>", self);
- }
+
+ return PyUnicode_FromFormat("<BMLoop dead at %p>", self);
}
/* Types
@@ -4054,12 +4013,10 @@ int bpy_bm_generic_valid_check(BPy_BMGeneric *self)
return 0;
}
- else {
- PyErr_Format(PyExc_ReferenceError,
- "BMesh data of type %.200s has been removed",
- Py_TYPE(self)->tp_name);
- return -1;
- }
+
+ PyErr_Format(
+ PyExc_ReferenceError, "BMesh data of type %.200s has been removed", Py_TYPE(self)->tp_name);
+ return -1;
}
int bpy_bm_generic_valid_check_source(BMesh *bm_source,
@@ -4079,16 +4036,15 @@ int bpy_bm_generic_valid_check_source(BMesh *bm_source,
if (UNLIKELY(ret == -1)) {
break;
}
- else {
- if (UNLIKELY(py_bm_elem->bm != bm_source)) {
- /* could give more info here */
- PyErr_Format(PyExc_ValueError,
- "%.200s: BMesh data of type %.200s is from another mesh",
- error_prefix,
- Py_TYPE(py_bm_elem)->tp_name);
- ret = -1;
- break;
- }
+
+ if (UNLIKELY(py_bm_elem->bm != bm_source)) {
+ /* could give more info here */
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: BMesh data of type %.200s is from another mesh",
+ error_prefix,
+ Py_TYPE(py_bm_elem)->tp_name);
+ ret = -1;
+ break;
}
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 8615da653ae..51616030d30 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -67,10 +67,9 @@ static CustomDataLayer *bpy_bmlayeritem_get(BPy_BMLayerItem *self)
if (index_absolute != -1) {
return &data->layers[index_absolute];
}
- else {
- PyErr_SetString(PyExc_RuntimeError, "layer has become invalid");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_RuntimeError, "layer has become invalid");
+ return NULL;
}
/* py-type definitions
@@ -142,9 +141,8 @@ static PyObject *bpy_bmlayercollection_active_get(BPy_BMLayerItem *self, void *U
if (index != -1) {
return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(
@@ -169,9 +167,8 @@ static PyObject *bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(fl
if (layer) {
return PyUnicode_FromString(layer->name);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = {
@@ -617,16 +614,15 @@ static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject
if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) {
return NULL;
}
- else {
- CustomData *data;
- int index;
- data = bpy_bm_customdata_get(self->bm, self->htype);
- index = CustomData_get_named_layer(data, self->type, key); /* type relative */
+ CustomData *data;
+ int index;
- if (index != -1) {
- return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
- }
+ data = bpy_bm_customdata_get(self->bm, self->htype);
+ index = CustomData_get_named_layer(data, self->type, key); /* type relative */
+
+ if (index != -1) {
+ return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
}
return Py_INCREF_RET(def);
@@ -689,10 +685,9 @@ static PyObject *bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self
if (index != -1) {
return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index);
}
- else {
- PyErr_Format(PyExc_KeyError, "BMLayerCollection[key]: key \"%.200s\" not found", keyname);
- return NULL;
- }
+
+ PyErr_Format(PyExc_KeyError, "BMLayerCollection[key]: key \"%.200s\" not found", keyname);
+ return NULL;
}
static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum)
@@ -750,62 +745,58 @@ static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, Py
if (PyUnicode_Check(key)) {
return bpy_bmlayercollection_subscript_str(self, _PyUnicode_AsString(key));
}
- else if (PyIndex_Check(key)) {
+ if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
return bpy_bmlayercollection_subscript_int(self, i);
}
- else if (PySlice_Check(key)) {
+ if (PySlice_Check(key)) {
PySliceObject *key_slice = (PySliceObject *)key;
Py_ssize_t step = 1;
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
- else if (step != 1) {
+ if (step != 1) {
PyErr_SetString(PyExc_TypeError, "BMLayerCollection[slice]: slice steps not supported");
return NULL;
}
- else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+ if (key_slice->start == Py_None && key_slice->stop == Py_None) {
return bpy_bmlayercollection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
- else {
- Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
- if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
- return NULL;
- }
- if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
- return NULL;
- }
+ Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- if (start < 0 || stop < 0) {
- /* only get the length for negative values */
- Py_ssize_t len = bpy_bmlayercollection_length(self);
- if (start < 0) {
- start += len;
- }
- if (stop < 0) {
- stop += len;
- }
- }
+ /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
+ return NULL;
+ }
+ if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
+ return NULL;
+ }
- if (stop - start <= 0) {
- return PyTuple_New(0);
+ if (start < 0 || stop < 0) {
+ /* only get the length for negative values */
+ Py_ssize_t len = bpy_bmlayercollection_length(self);
+ if (start < 0) {
+ start += len;
}
- else {
- return bpy_bmlayercollection_subscript_slice(self, start, stop);
+ if (stop < 0) {
+ stop += len;
}
}
+
+ if (stop - start <= 0) {
+ return PyTuple_New(0);
+ }
+
+ return bpy_bmlayercollection_subscript_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_AttributeError,
- "BMLayerCollection[key]: invalid key, key must be an int");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError, "BMLayerCollection[key]: invalid key, key must be an int");
+ return NULL;
}
static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject *value)
@@ -1024,11 +1015,11 @@ static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_lay
PyErr_SetString(PyExc_AttributeError, "BMElem[key]: invalid key, must be a BMLayerItem");
return NULL;
}
- else if (UNLIKELY(py_ele->bm != py_layer->bm)) {
+ if (UNLIKELY(py_ele->bm != py_layer->bm)) {
PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh");
return NULL;
}
- else if (UNLIKELY(ele->head.htype != py_layer->htype)) {
+ if (UNLIKELY(ele->head.htype != py_layer->htype)) {
char namestr_1[32], namestr_2[32];
PyErr_Format(PyExc_ValueError,
"Layer/Element type mismatch, expected %.200s got layer type %.200s",
@@ -1046,9 +1037,8 @@ static void *bpy_bmlayeritem_ptr_get(BPy_BMElem *py_ele, BPy_BMLayerItem *py_lay
PyErr_SetString(PyExc_KeyError, "BMElem[key]: layer not found");
return NULL;
}
- else {
- return value;
- }
+
+ return value;
}
/**
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 82b6cf5c3d5..f42348975c9 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -65,9 +65,8 @@ static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED
copy_v2_v2(self->data->uv, tvec);
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyDoc_STRVAR(bpy_bmloopuv_flag__pin_uv_doc, "UV pin state.\n\n:type: boolean");
@@ -136,10 +135,9 @@ int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value)
PyErr_Format(PyExc_TypeError, "expected BMLoopUV, not a %.200s", Py_TYPE(value)->tp_name);
return -1;
}
- else {
- *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data);
- return 0;
- }
+
+ *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data);
+ return 0;
}
PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv)
@@ -174,9 +172,8 @@ static int bpy_bmvertskin_radius_set(BPy_BMVertSkin *self, PyObject *value, void
copy_v2_v2(self->data->radius, tvec);
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyDoc_STRVAR(bpy_bmvertskin_flag__use_root_doc,
@@ -251,10 +248,9 @@ int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value)
PyErr_Format(PyExc_TypeError, "expected BMVertSkin, not a %.200s", Py_TYPE(value)->tp_name);
return -1;
}
- else {
- *((MVertSkin *)mvertskin) = *(((BPy_BMVertSkin *)value)->data);
- return 0;
- }
+
+ *((MVertSkin *)mvertskin) = *(((BPy_BMVertSkin *)value)->data);
+ return 0;
}
PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin)
@@ -351,9 +347,8 @@ int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *mloopcol, PyObject *value)
mloopcol_from_float(mloopcol, tvec);
return 0;
}
- else {
- return -1;
- }
+
+ return -1;
}
PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data)
@@ -416,25 +411,22 @@ static PyObject *bpy_bmdeformvert_subscript(BPy_BMDeformVert *self, PyObject *ke
if (i == -1 && PyErr_Occurred()) {
return NULL;
}
- else {
- MDeformWeight *dw = BKE_defvert_find_index(self->data, i);
- if (dw == NULL) {
- PyErr_SetString(PyExc_KeyError,
- "BMDeformVert[key] = x: "
- "key not found");
- return NULL;
- }
- else {
- return PyFloat_FromDouble(dw->weight);
- }
+ MDeformWeight *dw = BKE_defvert_find_index(self->data, i);
+
+ if (dw == NULL) {
+ PyErr_SetString(PyExc_KeyError,
+ "BMDeformVert[key] = x: "
+ "key not found");
+ return NULL;
}
+
+ return PyFloat_FromDouble(dw->weight);
}
- else {
- PyErr_Format(
- PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
- return NULL;
- }
+
+ PyErr_Format(
+ PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
+ return NULL;
}
static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key, PyObject *value)
@@ -455,18 +447,17 @@ static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key,
"weight keys can't be negative");
return -1;
}
- else {
- MDeformWeight *dw = BKE_defvert_ensure_index(self->data, i);
- const float f = PyFloat_AsDouble(value);
- if (f == -1 && PyErr_Occurred()) { // parsed key not a number
- PyErr_SetString(PyExc_TypeError,
- "BMDeformVert[key] = x: "
- "assigned value not a number");
- return -1;
- }
-
- dw->weight = clamp_f(f, 0.0f, 1.0f);
+
+ MDeformWeight *dw = BKE_defvert_ensure_index(self->data, i);
+ const float f = PyFloat_AsDouble(value);
+ if (f == -1 && PyErr_Occurred()) { // parsed key not a number
+ PyErr_SetString(PyExc_TypeError,
+ "BMDeformVert[key] = x: "
+ "assigned value not a number");
+ return -1;
}
+
+ dw->weight = clamp_f(f, 0.0f, 1.0f);
}
else {
/* del dvert[group_index] */
@@ -482,11 +473,10 @@ static int bpy_bmdeformvert_ass_subscript(BPy_BMDeformVert *self, PyObject *key,
return 0;
}
- else {
- PyErr_Format(
- PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
- return -1;
- }
+
+ PyErr_Format(
+ PyExc_TypeError, "BMDeformVert keys must be integers, not %.200s", Py_TYPE(key)->tp_name);
+ return -1;
}
static int bpy_bmdeformvert_contains(BPy_BMDeformVert *self, PyObject *value)
@@ -616,16 +606,14 @@ static PyObject *bpy_bmdeformvert_get(BPy_BMDeformVert *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i|O:get", &key, &def)) {
return NULL;
}
- else {
- MDeformWeight *dw = BKE_defvert_find_index(self->data, key);
- if (dw) {
- return PyFloat_FromDouble(dw->weight);
- }
- else {
- return Py_INCREF_RET(def);
- }
+ MDeformWeight *dw = BKE_defvert_find_index(self->data, key);
+
+ if (dw) {
+ return PyFloat_FromDouble(dw->weight);
}
+
+ return Py_INCREF_RET(def);
}
PyDoc_STRVAR(bpy_bmdeformvert_clear_doc,
@@ -675,13 +663,12 @@ int BPy_BMDeformVert_AssignPyObject(struct MDeformVert *dvert, PyObject *value)
PyErr_Format(PyExc_TypeError, "expected BMDeformVert, not a %.200s", Py_TYPE(value)->tp_name);
return -1;
}
- else {
- MDeformVert *dvert_src = ((BPy_BMDeformVert *)value)->data;
- if (LIKELY(dvert != dvert_src)) {
- BKE_defvert_copy(dvert, dvert_src);
- }
- return 0;
+
+ MDeformVert *dvert_src = ((BPy_BMDeformVert *)value)->data;
+ if (LIKELY(dvert != dvert_src)) {
+ BKE_defvert_copy(dvert, dvert_src);
}
+ return 0;
}
PyObject *BPy_BMDeformVert_CreatePyObject(struct MDeformVert *dvert)
diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c
index 5e064453a04..d69668341ff 100644
--- a/source/blender/python/bmesh/bmesh_py_types_select.c
+++ b/source/blender/python/bmesh/bmesh_py_types_select.c
@@ -51,9 +51,8 @@ static PyObject *bpy_bmeditselseq_active_get(BPy_BMEditSelSeq *self, void *UNUSE
if ((ese = self->bm->selected.last)) {
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
static PyGetSetDef bpy_bmeditselseq_getseters[] = {
@@ -196,10 +195,9 @@ static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keyn
if (ese) {
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
}
- else {
- PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum);
- return NULL;
- }
+
+ PyErr_Format(PyExc_IndexError, "BMElemSeq[index]: index %d out of range", keynum);
+ return NULL;
}
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self,
@@ -254,54 +252,51 @@ static PyObject *bpy_bmeditselseq_subscript(BPy_BMEditSelSeq *self, PyObject *ke
}
return bpy_bmeditselseq_subscript_int(self, i);
}
- else if (PySlice_Check(key)) {
+ if (PySlice_Check(key)) {
PySliceObject *key_slice = (PySliceObject *)key;
Py_ssize_t step = 1;
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
- else if (step != 1) {
+ if (step != 1) {
PyErr_SetString(PyExc_TypeError, "BMElemSeq[slice]: slice steps not supported");
return NULL;
}
- else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+ if (key_slice->start == Py_None && key_slice->stop == Py_None) {
return bpy_bmeditselseq_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
- else {
- Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
- if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
- return NULL;
- }
- if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
- return NULL;
- }
+ Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- if (start < 0 || stop < 0) {
- /* only get the length for negative values */
- Py_ssize_t len = bpy_bmeditselseq_length(self);
- if (start < 0) {
- start += len;
- }
- if (stop < 0) {
- stop += len;
- }
- }
+ /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
+ return NULL;
+ }
+ if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
+ return NULL;
+ }
- if (stop - start <= 0) {
- return PyList_New(0);
+ if (start < 0 || stop < 0) {
+ /* only get the length for negative values */
+ Py_ssize_t len = bpy_bmeditselseq_length(self);
+ if (start < 0) {
+ start += len;
}
- else {
- return bpy_bmeditselseq_subscript_slice(self, start, stop);
+ if (stop < 0) {
+ stop += len;
}
}
+
+ if (stop - start <= 0) {
+ return PyList_New(0);
+ }
+
+ return bpy_bmeditselseq_subscript_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int");
+ return NULL;
}
static int bpy_bmeditselseq_contains(BPy_BMEditSelSeq *self, PyObject *value)
@@ -358,10 +353,9 @@ static PyObject *bpy_bmeditseliter_next(BPy_BMEditSelIter *self)
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
- else {
- self->ese = ese->next;
- return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
- }
+
+ self->ese = ese->next;
+ return (PyObject *)BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
}
PyTypeObject BPy_BMEditSelSeq_Type;
diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c
index 9b207693e37..eab9ab226e4 100644
--- a/source/blender/python/bmesh/bmesh_py_utils.c
+++ b/source/blender/python/bmesh/bmesh_py_utils.c
@@ -91,11 +91,10 @@ static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObjec
if (e_new) {
return BPy_BMEdge_CreatePyObject(bm, e_new);
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "vert_collapse_edge(vert, edge): no new edge created, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "vert_collapse_edge(vert, edge): no new edge created, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bm_utils_vert_collapse_faces_doc,
@@ -158,11 +157,10 @@ static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObje
if (e_new) {
return BPy_BMEdge_CreatePyObject(bm, e_new);
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "vert_collapse_faces(vert, edge): no new edge created, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "vert_collapse_faces(vert, edge): no new edge created, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bm_utils_vert_dissolve_doc,
@@ -360,11 +358,10 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args)
ret, BPy_BMEdge_CreatePyObject(bm, e_new), BPy_BMVert_CreatePyObject(bm, v_new));
return ret;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "edge_split(edge, vert): couldn't split the edge, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "edge_split(edge, vert): couldn't split the edge, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bm_utils_edge_rotate_doc,
@@ -401,9 +398,8 @@ static PyObject *bpy_bm_utils_edge_rotate(PyObject *UNUSED(self), PyObject *args
if (e_new) {
return BPy_BMEdge_CreatePyObject(bm, e_new);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(
@@ -534,10 +530,9 @@ static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args,
ret, BPy_BMFace_CreatePyObject(bm, f_new), BPy_BMLoop_CreatePyObject(bm, l_new));
return ret;
}
- else {
- PyErr_SetString(PyExc_ValueError, "face_split(...): couldn't split the face, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError, "face_split(...): couldn't split the face, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bm_utils_face_split_edgenet_doc,
@@ -617,11 +612,10 @@ static PyObject *bpy_bm_utils_face_split_edgenet(PyObject *UNUSED(self),
}
return ret;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "face_split_edgenet(...): couldn't split the face, internal error");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "face_split_edgenet(...): couldn't split the face, internal error");
+ return NULL;
}
PyDoc_STRVAR(bpy_bm_utils_face_join_doc,
@@ -664,9 +658,8 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *args)
if (f_new) {
return BPy_BMFace_CreatePyObject(bm, f_new);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(
@@ -721,9 +714,8 @@ static PyObject *bpy_bm_utils_face_vert_separate(PyObject *UNUSED(self), PyObjec
if (v_new != v_old) {
return BPy_BMVert_CreatePyObject(bm, v_new);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(bpy_bm_utils_face_flip_doc,
@@ -782,9 +774,8 @@ static PyObject *bpy_bm_utils_loop_separate(PyObject *UNUSED(self), BPy_BMLoop *
if (v_new != v_old) {
return BPy_BMVert_CreatePyObject(bm, v_new);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
static struct PyMethodDef BPy_BM_utils_methods[] = {
diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c
index 2ad2794c76f..405541554c9 100644
--- a/source/blender/python/generic/bgl.c
+++ b/source/blender/python/generic/bgl.c
@@ -415,10 +415,9 @@ typedef struct BufferOrOffset {
if (ret_str) { \
return PyUnicode_FromString((const char *)ret_str); \
} \
- else { \
- PyErr_SetString(PyExc_AttributeError, "could not get opengl string"); \
- return NULL; \
- }
+\
+ PyErr_SetString(PyExc_AttributeError, "could not get opengl string"); \
+ return NULL;
/** \} */
@@ -705,7 +704,7 @@ static int BGL_BufferOrOffsetConverter(PyObject *object, BufferOrOffset *buffer)
buffer->offset = NULL;
return 1;
}
- else if (PyNumber_Check(object)) {
+ if (PyNumber_Check(object)) {
Py_ssize_t offset = PyNumber_AsSsize_t(object, PyExc_IndexError);
if (offset == -1 && PyErr_Occurred()) {
return 0;
@@ -715,15 +714,14 @@ static int BGL_BufferOrOffsetConverter(PyObject *object, BufferOrOffset *buffer)
buffer->offset = (void *)offset;
return 1;
}
- else if (PyObject_TypeCheck(object, &BGL_bufferType)) {
+ if (PyObject_TypeCheck(object, &BGL_bufferType)) {
buffer->buffer = (Buffer *)object;
buffer->offset = NULL;
return 1;
}
- else {
- PyErr_SetString(PyExc_TypeError, "expected a bgl.Buffer or None");
- return 0;
- }
+
+ PyErr_SetString(PyExc_TypeError, "expected a bgl.Buffer or None");
+ return 0;
}
#define MAX_DIMENSIONS 256
@@ -766,7 +764,7 @@ static PyObject *Buffer_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject
"too many dimensions, max is " STRINGIFY(MAX_DIMENSIONS));
return NULL;
}
- else if (ndimensions < 1) {
+ if (ndimensions < 1) {
PyErr_SetString(PyExc_AttributeError, "sequence must have at least one dimension");
return NULL;
}
@@ -913,9 +911,8 @@ static int Buffer_ass_item(Buffer *self, int i, PyObject *v)
Py_DECREF(row);
return ret;
}
- else {
- return -1;
- }
+
+ return -1;
}
switch (self->type) {
@@ -996,7 +993,7 @@ static PyObject *Buffer_subscript(Buffer *self, PyObject *item)
}
return Buffer_item(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) {
@@ -1006,19 +1003,17 @@ static PyObject *Buffer_subscript(Buffer *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Buffer_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value)
@@ -1033,7 +1028,7 @@ static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value)
}
return Buffer_ass_item(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->dimensions[0], &start, &stop, &step, &slicelength) < 0) {
@@ -1043,16 +1038,14 @@ static int Buffer_ass_subscript(Buffer *self, PyObject *item, PyObject *value)
if (step == 1) {
return Buffer_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "buffer indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
static void Buffer_dealloc(Buffer *self)
@@ -1442,24 +1435,10 @@ static void py_module_dict_add_method(PyObject *submodule,
}
}
-PyObject *BPyInit_bgl(void)
-{
- PyObject *submodule, *dict;
- submodule = PyModule_Create(&BGL_module_def);
- dict = PyModule_GetDict(submodule);
-
- if (PyType_Ready(&BGL_bufferType) < 0) {
- return NULL; /* should never happen */
- }
-
- PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType);
- Py_INCREF((PyObject *)&BGL_bufferType);
-
/* needed since some function pointers won't be NULL */
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Waddress"
#endif
-
#define PY_MOD_ADD_METHOD(func) \
{ \
static PyMethodDef method_def = {"gl" #func, Method_##func, METH_VARARGS}; \
@@ -1467,788 +1446,790 @@ PyObject *BPyInit_bgl(void)
} \
((void)0)
+static void init_bgl_version_1_0_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_1_0 */
- {
- PY_MOD_ADD_METHOD(BlendFunc);
- PY_MOD_ADD_METHOD(Clear);
- PY_MOD_ADD_METHOD(ClearColor);
- PY_MOD_ADD_METHOD(ClearDepth);
- PY_MOD_ADD_METHOD(ClearStencil);
- PY_MOD_ADD_METHOD(ColorMask);
- PY_MOD_ADD_METHOD(CullFace);
- PY_MOD_ADD_METHOD(DepthFunc);
- PY_MOD_ADD_METHOD(DepthMask);
- PY_MOD_ADD_METHOD(DepthRange);
- PY_MOD_ADD_METHOD(Disable);
- PY_MOD_ADD_METHOD(DrawBuffer);
- PY_MOD_ADD_METHOD(Enable);
- PY_MOD_ADD_METHOD(Finish);
- PY_MOD_ADD_METHOD(Flush);
- PY_MOD_ADD_METHOD(FrontFace);
- PY_MOD_ADD_METHOD(GetBooleanv);
- PY_MOD_ADD_METHOD(GetDoublev);
- PY_MOD_ADD_METHOD(GetError);
- PY_MOD_ADD_METHOD(GetFloatv);
- PY_MOD_ADD_METHOD(GetIntegerv);
- PY_MOD_ADD_METHOD(GetString);
- PY_MOD_ADD_METHOD(GetTexImage);
- PY_MOD_ADD_METHOD(GetTexLevelParameterfv);
- PY_MOD_ADD_METHOD(GetTexLevelParameteriv);
- PY_MOD_ADD_METHOD(GetTexParameterfv);
- PY_MOD_ADD_METHOD(GetTexParameteriv);
- PY_MOD_ADD_METHOD(Hint);
- PY_MOD_ADD_METHOD(IsEnabled);
- PY_MOD_ADD_METHOD(LineWidth);
- PY_MOD_ADD_METHOD(LogicOp);
- PY_MOD_ADD_METHOD(PixelStoref);
- PY_MOD_ADD_METHOD(PixelStorei);
- PY_MOD_ADD_METHOD(PointSize);
- PY_MOD_ADD_METHOD(PolygonMode);
- PY_MOD_ADD_METHOD(ReadBuffer);
- PY_MOD_ADD_METHOD(ReadPixels);
- PY_MOD_ADD_METHOD(Scissor);
- PY_MOD_ADD_METHOD(StencilFunc);
- PY_MOD_ADD_METHOD(StencilMask);
- PY_MOD_ADD_METHOD(StencilOp);
- PY_MOD_ADD_METHOD(TexImage1D);
- PY_MOD_ADD_METHOD(TexImage2D);
- PY_MOD_ADD_METHOD(TexParameterf);
- PY_MOD_ADD_METHOD(TexParameterfv);
- PY_MOD_ADD_METHOD(TexParameteri);
- PY_MOD_ADD_METHOD(TexParameteriv);
- PY_MOD_ADD_METHOD(Viewport);
- }
-
+ PY_MOD_ADD_METHOD(BlendFunc);
+ PY_MOD_ADD_METHOD(Clear);
+ PY_MOD_ADD_METHOD(ClearColor);
+ PY_MOD_ADD_METHOD(ClearDepth);
+ PY_MOD_ADD_METHOD(ClearStencil);
+ PY_MOD_ADD_METHOD(ColorMask);
+ PY_MOD_ADD_METHOD(CullFace);
+ PY_MOD_ADD_METHOD(DepthFunc);
+ PY_MOD_ADD_METHOD(DepthMask);
+ PY_MOD_ADD_METHOD(DepthRange);
+ PY_MOD_ADD_METHOD(Disable);
+ PY_MOD_ADD_METHOD(DrawBuffer);
+ PY_MOD_ADD_METHOD(Enable);
+ PY_MOD_ADD_METHOD(Finish);
+ PY_MOD_ADD_METHOD(Flush);
+ PY_MOD_ADD_METHOD(FrontFace);
+ PY_MOD_ADD_METHOD(GetBooleanv);
+ PY_MOD_ADD_METHOD(GetDoublev);
+ PY_MOD_ADD_METHOD(GetError);
+ PY_MOD_ADD_METHOD(GetFloatv);
+ PY_MOD_ADD_METHOD(GetIntegerv);
+ PY_MOD_ADD_METHOD(GetString);
+ PY_MOD_ADD_METHOD(GetTexImage);
+ PY_MOD_ADD_METHOD(GetTexLevelParameterfv);
+ PY_MOD_ADD_METHOD(GetTexLevelParameteriv);
+ PY_MOD_ADD_METHOD(GetTexParameterfv);
+ PY_MOD_ADD_METHOD(GetTexParameteriv);
+ PY_MOD_ADD_METHOD(Hint);
+ PY_MOD_ADD_METHOD(IsEnabled);
+ PY_MOD_ADD_METHOD(LineWidth);
+ PY_MOD_ADD_METHOD(LogicOp);
+ PY_MOD_ADD_METHOD(PixelStoref);
+ PY_MOD_ADD_METHOD(PixelStorei);
+ PY_MOD_ADD_METHOD(PointSize);
+ PY_MOD_ADD_METHOD(PolygonMode);
+ PY_MOD_ADD_METHOD(ReadBuffer);
+ PY_MOD_ADD_METHOD(ReadPixels);
+ PY_MOD_ADD_METHOD(Scissor);
+ PY_MOD_ADD_METHOD(StencilFunc);
+ PY_MOD_ADD_METHOD(StencilMask);
+ PY_MOD_ADD_METHOD(StencilOp);
+ PY_MOD_ADD_METHOD(TexImage1D);
+ PY_MOD_ADD_METHOD(TexImage2D);
+ PY_MOD_ADD_METHOD(TexParameterf);
+ PY_MOD_ADD_METHOD(TexParameterfv);
+ PY_MOD_ADD_METHOD(TexParameteri);
+ PY_MOD_ADD_METHOD(TexParameteriv);
+ PY_MOD_ADD_METHOD(Viewport);
+}
+static void init_bgl_version_1_1_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_1_1 */
- {
- PY_MOD_ADD_METHOD(BindTexture);
- PY_MOD_ADD_METHOD(CopyTexImage1D);
- PY_MOD_ADD_METHOD(CopyTexImage2D);
- PY_MOD_ADD_METHOD(CopyTexSubImage1D);
- PY_MOD_ADD_METHOD(CopyTexSubImage2D);
- PY_MOD_ADD_METHOD(DeleteTextures);
- PY_MOD_ADD_METHOD(DrawArrays);
- PY_MOD_ADD_METHOD(DrawElements);
- PY_MOD_ADD_METHOD(GenTextures);
- PY_MOD_ADD_METHOD(IsTexture);
- PY_MOD_ADD_METHOD(PolygonOffset);
- PY_MOD_ADD_METHOD(TexSubImage1D);
- PY_MOD_ADD_METHOD(TexSubImage2D);
- }
-
+ PY_MOD_ADD_METHOD(BindTexture);
+ PY_MOD_ADD_METHOD(CopyTexImage1D);
+ PY_MOD_ADD_METHOD(CopyTexImage2D);
+ PY_MOD_ADD_METHOD(CopyTexSubImage1D);
+ PY_MOD_ADD_METHOD(CopyTexSubImage2D);
+ PY_MOD_ADD_METHOD(DeleteTextures);
+ PY_MOD_ADD_METHOD(DrawArrays);
+ PY_MOD_ADD_METHOD(DrawElements);
+ PY_MOD_ADD_METHOD(GenTextures);
+ PY_MOD_ADD_METHOD(IsTexture);
+ PY_MOD_ADD_METHOD(PolygonOffset);
+ PY_MOD_ADD_METHOD(TexSubImage1D);
+ PY_MOD_ADD_METHOD(TexSubImage2D);
+}
+static void init_bgl_version_1_2_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_1_2 */
- {
- PY_MOD_ADD_METHOD(CopyTexSubImage3D);
- PY_MOD_ADD_METHOD(DrawRangeElements);
- PY_MOD_ADD_METHOD(TexImage3D);
- PY_MOD_ADD_METHOD(TexSubImage3D);
- }
-
+ PY_MOD_ADD_METHOD(CopyTexSubImage3D);
+ PY_MOD_ADD_METHOD(DrawRangeElements);
+ PY_MOD_ADD_METHOD(TexImage3D);
+ PY_MOD_ADD_METHOD(TexSubImage3D);
+}
+static void init_bgl_version_1_3_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_1_3 */
- {
- PY_MOD_ADD_METHOD(ActiveTexture);
- PY_MOD_ADD_METHOD(CompressedTexImage1D);
- PY_MOD_ADD_METHOD(CompressedTexImage2D);
- PY_MOD_ADD_METHOD(CompressedTexImage3D);
- PY_MOD_ADD_METHOD(CompressedTexSubImage1D);
- PY_MOD_ADD_METHOD(CompressedTexSubImage2D);
- PY_MOD_ADD_METHOD(CompressedTexSubImage3D);
- PY_MOD_ADD_METHOD(GetCompressedTexImage);
- PY_MOD_ADD_METHOD(SampleCoverage);
- }
-
+ PY_MOD_ADD_METHOD(ActiveTexture);
+ PY_MOD_ADD_METHOD(CompressedTexImage1D);
+ PY_MOD_ADD_METHOD(CompressedTexImage2D);
+ PY_MOD_ADD_METHOD(CompressedTexImage3D);
+ PY_MOD_ADD_METHOD(CompressedTexSubImage1D);
+ PY_MOD_ADD_METHOD(CompressedTexSubImage2D);
+ PY_MOD_ADD_METHOD(CompressedTexSubImage3D);
+ PY_MOD_ADD_METHOD(GetCompressedTexImage);
+ PY_MOD_ADD_METHOD(SampleCoverage);
+}
+static void init_bgl_version_1_4_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_1_4 */
- {
- PY_MOD_ADD_METHOD(BlendColor);
- PY_MOD_ADD_METHOD(BlendEquation);
- }
-
- /* GL_VERSION_1_5 */
- {
- PY_MOD_ADD_METHOD(BeginQuery);
- PY_MOD_ADD_METHOD(BindBuffer);
- PY_MOD_ADD_METHOD(BufferData);
- PY_MOD_ADD_METHOD(BufferSubData);
- PY_MOD_ADD_METHOD(DeleteBuffers);
- PY_MOD_ADD_METHOD(DeleteQueries);
- PY_MOD_ADD_METHOD(EndQuery);
- PY_MOD_ADD_METHOD(GenBuffers);
- PY_MOD_ADD_METHOD(GenQueries);
- PY_MOD_ADD_METHOD(GetBufferParameteriv);
- PY_MOD_ADD_METHOD(GetBufferPointerv);
- PY_MOD_ADD_METHOD(GetBufferSubData);
- PY_MOD_ADD_METHOD(GetQueryObjectiv);
- PY_MOD_ADD_METHOD(GetQueryObjectuiv);
- PY_MOD_ADD_METHOD(GetQueryiv);
- PY_MOD_ADD_METHOD(IsBuffer);
- PY_MOD_ADD_METHOD(IsQuery);
- PY_MOD_ADD_METHOD(MapBuffer);
- PY_MOD_ADD_METHOD(UnmapBuffer);
- }
-
+ PY_MOD_ADD_METHOD(BlendColor);
+ PY_MOD_ADD_METHOD(BlendEquation);
+}
+static void init_bgl_version_1_5_methods(PyObject *submodule, PyObject *dict)
+/* GL_VERSION_1_5 */
+{
+ PY_MOD_ADD_METHOD(BeginQuery);
+ PY_MOD_ADD_METHOD(BindBuffer);
+ PY_MOD_ADD_METHOD(BufferData);
+ PY_MOD_ADD_METHOD(BufferSubData);
+ PY_MOD_ADD_METHOD(DeleteBuffers);
+ PY_MOD_ADD_METHOD(DeleteQueries);
+ PY_MOD_ADD_METHOD(EndQuery);
+ PY_MOD_ADD_METHOD(GenBuffers);
+ PY_MOD_ADD_METHOD(GenQueries);
+ PY_MOD_ADD_METHOD(GetBufferParameteriv);
+ PY_MOD_ADD_METHOD(GetBufferPointerv);
+ PY_MOD_ADD_METHOD(GetBufferSubData);
+ PY_MOD_ADD_METHOD(GetQueryObjectiv);
+ PY_MOD_ADD_METHOD(GetQueryObjectuiv);
+ PY_MOD_ADD_METHOD(GetQueryiv);
+ PY_MOD_ADD_METHOD(IsBuffer);
+ PY_MOD_ADD_METHOD(IsQuery);
+ PY_MOD_ADD_METHOD(MapBuffer);
+ PY_MOD_ADD_METHOD(UnmapBuffer);
+}
+static void init_bgl_version_2_0_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_2_0 */
- {
- PY_MOD_ADD_METHOD(AttachShader);
- PY_MOD_ADD_METHOD(BindAttribLocation);
- PY_MOD_ADD_METHOD(BlendEquationSeparate);
- PY_MOD_ADD_METHOD(CompileShader);
- PY_MOD_ADD_METHOD(CreateProgram);
- PY_MOD_ADD_METHOD(CreateShader);
- PY_MOD_ADD_METHOD(DeleteProgram);
- PY_MOD_ADD_METHOD(DeleteShader);
- PY_MOD_ADD_METHOD(DetachShader);
- PY_MOD_ADD_METHOD(DisableVertexAttribArray);
- PY_MOD_ADD_METHOD(DrawBuffers);
- PY_MOD_ADD_METHOD(EnableVertexAttribArray);
- PY_MOD_ADD_METHOD(GetActiveAttrib);
- PY_MOD_ADD_METHOD(GetActiveUniform);
- PY_MOD_ADD_METHOD(GetAttachedShaders);
- PY_MOD_ADD_METHOD(GetAttribLocation);
- PY_MOD_ADD_METHOD(GetProgramInfoLog);
- PY_MOD_ADD_METHOD(GetProgramiv);
- PY_MOD_ADD_METHOD(GetShaderInfoLog);
- PY_MOD_ADD_METHOD(GetShaderSource);
- PY_MOD_ADD_METHOD(GetShaderiv);
- PY_MOD_ADD_METHOD(GetUniformLocation);
- PY_MOD_ADD_METHOD(GetUniformfv);
- PY_MOD_ADD_METHOD(GetUniformiv);
- PY_MOD_ADD_METHOD(GetVertexAttribPointerv);
- PY_MOD_ADD_METHOD(GetVertexAttribdv);
- PY_MOD_ADD_METHOD(GetVertexAttribfv);
- PY_MOD_ADD_METHOD(GetVertexAttribiv);
- PY_MOD_ADD_METHOD(IsProgram);
- PY_MOD_ADD_METHOD(IsShader);
- PY_MOD_ADD_METHOD(LinkProgram);
- PY_MOD_ADD_METHOD(ShaderSource);
- PY_MOD_ADD_METHOD(StencilFuncSeparate);
- PY_MOD_ADD_METHOD(StencilMaskSeparate);
- PY_MOD_ADD_METHOD(StencilOpSeparate);
- PY_MOD_ADD_METHOD(Uniform1f);
- PY_MOD_ADD_METHOD(Uniform1fv);
- PY_MOD_ADD_METHOD(Uniform1i);
- PY_MOD_ADD_METHOD(Uniform1iv);
- PY_MOD_ADD_METHOD(Uniform2f);
- PY_MOD_ADD_METHOD(Uniform2fv);
- PY_MOD_ADD_METHOD(Uniform2i);
- PY_MOD_ADD_METHOD(Uniform2iv);
- PY_MOD_ADD_METHOD(Uniform3f);
- PY_MOD_ADD_METHOD(Uniform3fv);
- PY_MOD_ADD_METHOD(Uniform3i);
- PY_MOD_ADD_METHOD(Uniform3iv);
- PY_MOD_ADD_METHOD(Uniform4f);
- PY_MOD_ADD_METHOD(Uniform4fv);
- PY_MOD_ADD_METHOD(Uniform4i);
- PY_MOD_ADD_METHOD(Uniform4iv);
- PY_MOD_ADD_METHOD(UniformMatrix2fv);
- PY_MOD_ADD_METHOD(UniformMatrix3fv);
- PY_MOD_ADD_METHOD(UniformMatrix4fv);
- PY_MOD_ADD_METHOD(UseProgram);
- PY_MOD_ADD_METHOD(ValidateProgram);
- PY_MOD_ADD_METHOD(VertexAttrib1d);
- PY_MOD_ADD_METHOD(VertexAttrib1dv);
- PY_MOD_ADD_METHOD(VertexAttrib1f);
- PY_MOD_ADD_METHOD(VertexAttrib1fv);
- PY_MOD_ADD_METHOD(VertexAttrib1s);
- PY_MOD_ADD_METHOD(VertexAttrib1sv);
- PY_MOD_ADD_METHOD(VertexAttrib2d);
- PY_MOD_ADD_METHOD(VertexAttrib2dv);
- PY_MOD_ADD_METHOD(VertexAttrib2f);
- PY_MOD_ADD_METHOD(VertexAttrib2fv);
- PY_MOD_ADD_METHOD(VertexAttrib2s);
- PY_MOD_ADD_METHOD(VertexAttrib2sv);
- PY_MOD_ADD_METHOD(VertexAttrib3d);
- PY_MOD_ADD_METHOD(VertexAttrib3dv);
- PY_MOD_ADD_METHOD(VertexAttrib3f);
- PY_MOD_ADD_METHOD(VertexAttrib3fv);
- PY_MOD_ADD_METHOD(VertexAttrib3s);
- PY_MOD_ADD_METHOD(VertexAttrib3sv);
- PY_MOD_ADD_METHOD(VertexAttrib4Nbv);
- PY_MOD_ADD_METHOD(VertexAttrib4Niv);
- PY_MOD_ADD_METHOD(VertexAttrib4Nsv);
- PY_MOD_ADD_METHOD(VertexAttrib4Nub);
- PY_MOD_ADD_METHOD(VertexAttrib4Nubv);
- PY_MOD_ADD_METHOD(VertexAttrib4Nuiv);
- PY_MOD_ADD_METHOD(VertexAttrib4Nusv);
- PY_MOD_ADD_METHOD(VertexAttrib4bv);
- PY_MOD_ADD_METHOD(VertexAttrib4d);
- PY_MOD_ADD_METHOD(VertexAttrib4dv);
- PY_MOD_ADD_METHOD(VertexAttrib4f);
- PY_MOD_ADD_METHOD(VertexAttrib4fv);
- PY_MOD_ADD_METHOD(VertexAttrib4iv);
- PY_MOD_ADD_METHOD(VertexAttrib4s);
- PY_MOD_ADD_METHOD(VertexAttrib4sv);
- PY_MOD_ADD_METHOD(VertexAttrib4ubv);
- PY_MOD_ADD_METHOD(VertexAttrib4uiv);
- PY_MOD_ADD_METHOD(VertexAttrib4usv);
- PY_MOD_ADD_METHOD(VertexAttribPointer);
- }
-
+ PY_MOD_ADD_METHOD(AttachShader);
+ PY_MOD_ADD_METHOD(BindAttribLocation);
+ PY_MOD_ADD_METHOD(BlendEquationSeparate);
+ PY_MOD_ADD_METHOD(CompileShader);
+ PY_MOD_ADD_METHOD(CreateProgram);
+ PY_MOD_ADD_METHOD(CreateShader);
+ PY_MOD_ADD_METHOD(DeleteProgram);
+ PY_MOD_ADD_METHOD(DeleteShader);
+ PY_MOD_ADD_METHOD(DetachShader);
+ PY_MOD_ADD_METHOD(DisableVertexAttribArray);
+ PY_MOD_ADD_METHOD(DrawBuffers);
+ PY_MOD_ADD_METHOD(EnableVertexAttribArray);
+ PY_MOD_ADD_METHOD(GetActiveAttrib);
+ PY_MOD_ADD_METHOD(GetActiveUniform);
+ PY_MOD_ADD_METHOD(GetAttachedShaders);
+ PY_MOD_ADD_METHOD(GetAttribLocation);
+ PY_MOD_ADD_METHOD(GetProgramInfoLog);
+ PY_MOD_ADD_METHOD(GetProgramiv);
+ PY_MOD_ADD_METHOD(GetShaderInfoLog);
+ PY_MOD_ADD_METHOD(GetShaderSource);
+ PY_MOD_ADD_METHOD(GetShaderiv);
+ PY_MOD_ADD_METHOD(GetUniformLocation);
+ PY_MOD_ADD_METHOD(GetUniformfv);
+ PY_MOD_ADD_METHOD(GetUniformiv);
+ PY_MOD_ADD_METHOD(GetVertexAttribPointerv);
+ PY_MOD_ADD_METHOD(GetVertexAttribdv);
+ PY_MOD_ADD_METHOD(GetVertexAttribfv);
+ PY_MOD_ADD_METHOD(GetVertexAttribiv);
+ PY_MOD_ADD_METHOD(IsProgram);
+ PY_MOD_ADD_METHOD(IsShader);
+ PY_MOD_ADD_METHOD(LinkProgram);
+ PY_MOD_ADD_METHOD(ShaderSource);
+ PY_MOD_ADD_METHOD(StencilFuncSeparate);
+ PY_MOD_ADD_METHOD(StencilMaskSeparate);
+ PY_MOD_ADD_METHOD(StencilOpSeparate);
+ PY_MOD_ADD_METHOD(Uniform1f);
+ PY_MOD_ADD_METHOD(Uniform1fv);
+ PY_MOD_ADD_METHOD(Uniform1i);
+ PY_MOD_ADD_METHOD(Uniform1iv);
+ PY_MOD_ADD_METHOD(Uniform2f);
+ PY_MOD_ADD_METHOD(Uniform2fv);
+ PY_MOD_ADD_METHOD(Uniform2i);
+ PY_MOD_ADD_METHOD(Uniform2iv);
+ PY_MOD_ADD_METHOD(Uniform3f);
+ PY_MOD_ADD_METHOD(Uniform3fv);
+ PY_MOD_ADD_METHOD(Uniform3i);
+ PY_MOD_ADD_METHOD(Uniform3iv);
+ PY_MOD_ADD_METHOD(Uniform4f);
+ PY_MOD_ADD_METHOD(Uniform4fv);
+ PY_MOD_ADD_METHOD(Uniform4i);
+ PY_MOD_ADD_METHOD(Uniform4iv);
+ PY_MOD_ADD_METHOD(UniformMatrix2fv);
+ PY_MOD_ADD_METHOD(UniformMatrix3fv);
+ PY_MOD_ADD_METHOD(UniformMatrix4fv);
+ PY_MOD_ADD_METHOD(UseProgram);
+ PY_MOD_ADD_METHOD(ValidateProgram);
+ PY_MOD_ADD_METHOD(VertexAttrib1d);
+ PY_MOD_ADD_METHOD(VertexAttrib1dv);
+ PY_MOD_ADD_METHOD(VertexAttrib1f);
+ PY_MOD_ADD_METHOD(VertexAttrib1fv);
+ PY_MOD_ADD_METHOD(VertexAttrib1s);
+ PY_MOD_ADD_METHOD(VertexAttrib1sv);
+ PY_MOD_ADD_METHOD(VertexAttrib2d);
+ PY_MOD_ADD_METHOD(VertexAttrib2dv);
+ PY_MOD_ADD_METHOD(VertexAttrib2f);
+ PY_MOD_ADD_METHOD(VertexAttrib2fv);
+ PY_MOD_ADD_METHOD(VertexAttrib2s);
+ PY_MOD_ADD_METHOD(VertexAttrib2sv);
+ PY_MOD_ADD_METHOD(VertexAttrib3d);
+ PY_MOD_ADD_METHOD(VertexAttrib3dv);
+ PY_MOD_ADD_METHOD(VertexAttrib3f);
+ PY_MOD_ADD_METHOD(VertexAttrib3fv);
+ PY_MOD_ADD_METHOD(VertexAttrib3s);
+ PY_MOD_ADD_METHOD(VertexAttrib3sv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nbv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Niv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nsv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nub);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nubv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nuiv);
+ PY_MOD_ADD_METHOD(VertexAttrib4Nusv);
+ PY_MOD_ADD_METHOD(VertexAttrib4bv);
+ PY_MOD_ADD_METHOD(VertexAttrib4d);
+ PY_MOD_ADD_METHOD(VertexAttrib4dv);
+ PY_MOD_ADD_METHOD(VertexAttrib4f);
+ PY_MOD_ADD_METHOD(VertexAttrib4fv);
+ PY_MOD_ADD_METHOD(VertexAttrib4iv);
+ PY_MOD_ADD_METHOD(VertexAttrib4s);
+ PY_MOD_ADD_METHOD(VertexAttrib4sv);
+ PY_MOD_ADD_METHOD(VertexAttrib4ubv);
+ PY_MOD_ADD_METHOD(VertexAttrib4uiv);
+ PY_MOD_ADD_METHOD(VertexAttrib4usv);
+ PY_MOD_ADD_METHOD(VertexAttribPointer);
+}
+static void init_bgl_version_2_1_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_2_1 */
- {
- PY_MOD_ADD_METHOD(UniformMatrix2x3fv);
- PY_MOD_ADD_METHOD(UniformMatrix2x4fv);
- PY_MOD_ADD_METHOD(UniformMatrix3x2fv);
- PY_MOD_ADD_METHOD(UniformMatrix3x4fv);
- PY_MOD_ADD_METHOD(UniformMatrix4x2fv);
- PY_MOD_ADD_METHOD(UniformMatrix4x3fv);
- }
-
+ PY_MOD_ADD_METHOD(UniformMatrix2x3fv);
+ PY_MOD_ADD_METHOD(UniformMatrix2x4fv);
+ PY_MOD_ADD_METHOD(UniformMatrix3x2fv);
+ PY_MOD_ADD_METHOD(UniformMatrix3x4fv);
+ PY_MOD_ADD_METHOD(UniformMatrix4x2fv);
+ PY_MOD_ADD_METHOD(UniformMatrix4x3fv);
+}
+static void init_bgl_version_3_0_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_3_0 */
- {
- PY_MOD_ADD_METHOD(BindFramebuffer);
- PY_MOD_ADD_METHOD(BindRenderbuffer);
- PY_MOD_ADD_METHOD(BindVertexArray);
- PY_MOD_ADD_METHOD(BlitFramebuffer);
- PY_MOD_ADD_METHOD(CheckFramebufferStatus);
- PY_MOD_ADD_METHOD(DeleteFramebuffers);
- PY_MOD_ADD_METHOD(DeleteRenderbuffers);
- PY_MOD_ADD_METHOD(DeleteVertexArrays);
- PY_MOD_ADD_METHOD(FramebufferRenderbuffer);
- PY_MOD_ADD_METHOD(GenFramebuffers);
- PY_MOD_ADD_METHOD(GenRenderbuffers);
- PY_MOD_ADD_METHOD(GenVertexArrays);
- PY_MOD_ADD_METHOD(GetStringi);
- PY_MOD_ADD_METHOD(IsVertexArray);
- PY_MOD_ADD_METHOD(RenderbufferStorage);
- PY_MOD_ADD_METHOD(VertexAttribIPointer);
- }
-
+ PY_MOD_ADD_METHOD(BindFramebuffer);
+ PY_MOD_ADD_METHOD(BindRenderbuffer);
+ PY_MOD_ADD_METHOD(BindVertexArray);
+ PY_MOD_ADD_METHOD(BlitFramebuffer);
+ PY_MOD_ADD_METHOD(CheckFramebufferStatus);
+ PY_MOD_ADD_METHOD(DeleteFramebuffers);
+ PY_MOD_ADD_METHOD(DeleteRenderbuffers);
+ PY_MOD_ADD_METHOD(DeleteVertexArrays);
+ PY_MOD_ADD_METHOD(FramebufferRenderbuffer);
+ PY_MOD_ADD_METHOD(GenFramebuffers);
+ PY_MOD_ADD_METHOD(GenRenderbuffers);
+ PY_MOD_ADD_METHOD(GenVertexArrays);
+ PY_MOD_ADD_METHOD(GetStringi);
+ PY_MOD_ADD_METHOD(IsVertexArray);
+ PY_MOD_ADD_METHOD(RenderbufferStorage);
+ PY_MOD_ADD_METHOD(VertexAttribIPointer);
+}
+static void init_bgl_version_3_1_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_3_1 */
- {
- PY_MOD_ADD_METHOD(BindBufferBase);
- PY_MOD_ADD_METHOD(BindBufferRange);
- PY_MOD_ADD_METHOD(GetActiveUniformBlockName);
- PY_MOD_ADD_METHOD(GetActiveUniformBlockiv);
- PY_MOD_ADD_METHOD(GetActiveUniformName);
- PY_MOD_ADD_METHOD(GetActiveUniformsiv);
- PY_MOD_ADD_METHOD(GetIntegeri_v);
- PY_MOD_ADD_METHOD(GetUniformBlockIndex);
- PY_MOD_ADD_METHOD(GetUniformIndices);
- PY_MOD_ADD_METHOD(UniformBlockBinding);
- }
-
+ PY_MOD_ADD_METHOD(BindBufferBase);
+ PY_MOD_ADD_METHOD(BindBufferRange);
+ PY_MOD_ADD_METHOD(GetActiveUniformBlockName);
+ PY_MOD_ADD_METHOD(GetActiveUniformBlockiv);
+ PY_MOD_ADD_METHOD(GetActiveUniformName);
+ PY_MOD_ADD_METHOD(GetActiveUniformsiv);
+ PY_MOD_ADD_METHOD(GetIntegeri_v);
+ PY_MOD_ADD_METHOD(GetUniformBlockIndex);
+ PY_MOD_ADD_METHOD(GetUniformIndices);
+ PY_MOD_ADD_METHOD(UniformBlockBinding);
+}
+static void init_bgl_version_3_2_methods(PyObject *submodule, PyObject *dict)
+{
/* GL_VERSION_3_2 */
- {
- PY_MOD_ADD_METHOD(FramebufferTexture);
- PY_MOD_ADD_METHOD(GetBufferParameteri64v);
- PY_MOD_ADD_METHOD(GetInteger64i_v);
- PY_MOD_ADD_METHOD(GetMultisamplefv);
- PY_MOD_ADD_METHOD(SampleMaski);
- PY_MOD_ADD_METHOD(TexImage2DMultisample);
- PY_MOD_ADD_METHOD(TexImage3DMultisample);
- }
-
+ PY_MOD_ADD_METHOD(FramebufferTexture);
+ PY_MOD_ADD_METHOD(GetBufferParameteri64v);
+ PY_MOD_ADD_METHOD(GetInteger64i_v);
+ PY_MOD_ADD_METHOD(GetMultisamplefv);
+ PY_MOD_ADD_METHOD(SampleMaski);
+ PY_MOD_ADD_METHOD(TexImage2DMultisample);
+ PY_MOD_ADD_METHOD(TexImage3DMultisample);
+}
+static void init_bgl_version_3_3_methods(PyObject *UNUSED(submodule), PyObject *UNUSED(dict))
+{
/* GL_VERSION_3_3 */
- {
- }
+}
#define PY_DICT_ADD_INT(x) py_module_dict_add_int(dict, #x, x)
#define PY_DICT_ADD_INT64(x) py_module_dict_add_int64(dict, #x, x)
+static void init_bgl_version_1_1_constants(PyObject *dict)
+{
/* GL_VERSION_1_1 */
- {
- PY_DICT_ADD_INT(GL_ALPHA);
- PY_DICT_ADD_INT(GL_ALWAYS);
- PY_DICT_ADD_INT(GL_AND);
- PY_DICT_ADD_INT(GL_AND_INVERTED);
- PY_DICT_ADD_INT(GL_AND_REVERSE);
- PY_DICT_ADD_INT(GL_BACK);
- PY_DICT_ADD_INT(GL_BACK_LEFT);
- PY_DICT_ADD_INT(GL_BACK_RIGHT);
- PY_DICT_ADD_INT(GL_BLEND);
- PY_DICT_ADD_INT(GL_BLEND_DST);
- PY_DICT_ADD_INT(GL_BLEND_SRC);
- PY_DICT_ADD_INT(GL_BLUE);
- PY_DICT_ADD_INT(GL_BYTE);
- PY_DICT_ADD_INT(GL_CCW);
- PY_DICT_ADD_INT(GL_CLEAR);
- PY_DICT_ADD_INT(GL_COLOR);
- PY_DICT_ADD_INT(GL_COLOR_BUFFER_BIT);
- PY_DICT_ADD_INT(GL_COLOR_CLEAR_VALUE);
- PY_DICT_ADD_INT(GL_COLOR_LOGIC_OP);
- PY_DICT_ADD_INT(GL_COLOR_WRITEMASK);
- PY_DICT_ADD_INT(GL_COPY);
- PY_DICT_ADD_INT(GL_COPY_INVERTED);
- PY_DICT_ADD_INT(GL_CULL_FACE);
- PY_DICT_ADD_INT(GL_CULL_FACE_MODE);
- PY_DICT_ADD_INT(GL_CW);
- PY_DICT_ADD_INT(GL_DECR);
- PY_DICT_ADD_INT(GL_DEPTH);
- PY_DICT_ADD_INT(GL_DEPTH_BUFFER_BIT);
- PY_DICT_ADD_INT(GL_DEPTH_CLEAR_VALUE);
- PY_DICT_ADD_INT(GL_DEPTH_COMPONENT);
- PY_DICT_ADD_INT(GL_DEPTH_FUNC);
- PY_DICT_ADD_INT(GL_DEPTH_RANGE);
- PY_DICT_ADD_INT(GL_DEPTH_TEST);
- PY_DICT_ADD_INT(GL_DEPTH_WRITEMASK);
- PY_DICT_ADD_INT(GL_DITHER);
- PY_DICT_ADD_INT(GL_DONT_CARE);
- PY_DICT_ADD_INT(GL_DOUBLE);
- PY_DICT_ADD_INT(GL_DOUBLEBUFFER);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER);
- PY_DICT_ADD_INT(GL_DST_ALPHA);
- PY_DICT_ADD_INT(GL_DST_COLOR);
- PY_DICT_ADD_INT(GL_EQUAL);
- PY_DICT_ADD_INT(GL_EQUIV);
- PY_DICT_ADD_INT(GL_EXTENSIONS);
- PY_DICT_ADD_INT(GL_FALSE);
- PY_DICT_ADD_INT(GL_FASTEST);
- PY_DICT_ADD_INT(GL_FILL);
- PY_DICT_ADD_INT(GL_FLOAT);
- PY_DICT_ADD_INT(GL_FRONT);
- PY_DICT_ADD_INT(GL_FRONT_AND_BACK);
- PY_DICT_ADD_INT(GL_FRONT_FACE);
- PY_DICT_ADD_INT(GL_FRONT_LEFT);
- PY_DICT_ADD_INT(GL_FRONT_RIGHT);
- PY_DICT_ADD_INT(GL_GEQUAL);
- PY_DICT_ADD_INT(GL_GREATER);
- PY_DICT_ADD_INT(GL_GREEN);
- PY_DICT_ADD_INT(GL_INCR);
- PY_DICT_ADD_INT(GL_INT);
- PY_DICT_ADD_INT(GL_INVALID_ENUM);
- PY_DICT_ADD_INT(GL_INVALID_OPERATION);
- PY_DICT_ADD_INT(GL_INVALID_VALUE);
- PY_DICT_ADD_INT(GL_INVERT);
- PY_DICT_ADD_INT(GL_KEEP);
- PY_DICT_ADD_INT(GL_LEFT);
- PY_DICT_ADD_INT(GL_LEQUAL);
- PY_DICT_ADD_INT(GL_LESS);
- PY_DICT_ADD_INT(GL_LINE);
- PY_DICT_ADD_INT(GL_LINEAR);
- PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_LINEAR);
- PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_NEAREST);
- PY_DICT_ADD_INT(GL_LINES);
- PY_DICT_ADD_INT(GL_LINE_LOOP);
- PY_DICT_ADD_INT(GL_LINE_SMOOTH);
- PY_DICT_ADD_INT(GL_LINE_SMOOTH_HINT);
- PY_DICT_ADD_INT(GL_LINE_STRIP);
- PY_DICT_ADD_INT(GL_LINE_WIDTH);
- PY_DICT_ADD_INT(GL_LINE_WIDTH_GRANULARITY);
- PY_DICT_ADD_INT(GL_LINE_WIDTH_RANGE);
- PY_DICT_ADD_INT(GL_LOGIC_OP_MODE);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_SIZE);
- PY_DICT_ADD_INT(GL_MAX_VIEWPORT_DIMS);
- PY_DICT_ADD_INT(GL_NAND);
- PY_DICT_ADD_INT(GL_NEAREST);
- PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_LINEAR);
- PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_NEAREST);
- PY_DICT_ADD_INT(GL_NEVER);
- PY_DICT_ADD_INT(GL_NICEST);
- PY_DICT_ADD_INT(GL_NONE);
- PY_DICT_ADD_INT(GL_NOOP);
- PY_DICT_ADD_INT(GL_NOR);
- PY_DICT_ADD_INT(GL_NOTEQUAL);
- PY_DICT_ADD_INT(GL_NO_ERROR);
- PY_DICT_ADD_INT(GL_ONE);
- PY_DICT_ADD_INT(GL_ONE_MINUS_DST_ALPHA);
- PY_DICT_ADD_INT(GL_ONE_MINUS_DST_COLOR);
- PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_ALPHA);
- PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_COLOR);
- PY_DICT_ADD_INT(GL_OR);
- PY_DICT_ADD_INT(GL_OR_INVERTED);
- PY_DICT_ADD_INT(GL_OR_REVERSE);
- PY_DICT_ADD_INT(GL_OUT_OF_MEMORY);
- PY_DICT_ADD_INT(GL_PACK_ALIGNMENT);
- PY_DICT_ADD_INT(GL_PACK_LSB_FIRST);
- PY_DICT_ADD_INT(GL_PACK_ROW_LENGTH);
- PY_DICT_ADD_INT(GL_PACK_SKIP_PIXELS);
- PY_DICT_ADD_INT(GL_PACK_SKIP_ROWS);
- PY_DICT_ADD_INT(GL_PACK_SWAP_BYTES);
- PY_DICT_ADD_INT(GL_POINT);
- PY_DICT_ADD_INT(GL_POINTS);
- PY_DICT_ADD_INT(GL_POINT_SIZE);
- PY_DICT_ADD_INT(GL_POLYGON_MODE);
- PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FACTOR);
- PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FILL);
- PY_DICT_ADD_INT(GL_POLYGON_OFFSET_LINE);
- PY_DICT_ADD_INT(GL_POLYGON_OFFSET_POINT);
- PY_DICT_ADD_INT(GL_POLYGON_OFFSET_UNITS);
- PY_DICT_ADD_INT(GL_POLYGON_SMOOTH);
- PY_DICT_ADD_INT(GL_POLYGON_SMOOTH_HINT);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D);
- PY_DICT_ADD_INT(GL_R3_G3_B2);
- PY_DICT_ADD_INT(GL_READ_BUFFER);
- PY_DICT_ADD_INT(GL_RED);
- PY_DICT_ADD_INT(GL_RENDERER);
- PY_DICT_ADD_INT(GL_REPEAT);
- PY_DICT_ADD_INT(GL_REPLACE);
- PY_DICT_ADD_INT(GL_RGB);
- PY_DICT_ADD_INT(GL_RGB10);
- PY_DICT_ADD_INT(GL_RGB10_A2);
- PY_DICT_ADD_INT(GL_RGB12);
- PY_DICT_ADD_INT(GL_RGB16);
- PY_DICT_ADD_INT(GL_RGB4);
- PY_DICT_ADD_INT(GL_RGB5);
- PY_DICT_ADD_INT(GL_RGB5_A1);
- PY_DICT_ADD_INT(GL_RGB8);
- PY_DICT_ADD_INT(GL_RGBA);
- PY_DICT_ADD_INT(GL_RGBA12);
- PY_DICT_ADD_INT(GL_RGBA16);
- PY_DICT_ADD_INT(GL_RGBA2);
- PY_DICT_ADD_INT(GL_RGBA4);
- PY_DICT_ADD_INT(GL_RGBA8);
- PY_DICT_ADD_INT(GL_RIGHT);
- PY_DICT_ADD_INT(GL_SCISSOR_BOX);
- PY_DICT_ADD_INT(GL_SCISSOR_TEST);
- PY_DICT_ADD_INT(GL_SET);
- PY_DICT_ADD_INT(GL_SHORT);
- PY_DICT_ADD_INT(GL_SRC_ALPHA);
- PY_DICT_ADD_INT(GL_SRC_ALPHA_SATURATE);
- PY_DICT_ADD_INT(GL_SRC_COLOR);
- PY_DICT_ADD_INT(GL_STENCIL);
- PY_DICT_ADD_INT(GL_STENCIL_BUFFER_BIT);
- PY_DICT_ADD_INT(GL_STENCIL_CLEAR_VALUE);
- PY_DICT_ADD_INT(GL_STENCIL_FAIL);
- PY_DICT_ADD_INT(GL_STENCIL_FUNC);
- PY_DICT_ADD_INT(GL_STENCIL_INDEX);
- PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_FAIL);
- PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_PASS);
- PY_DICT_ADD_INT(GL_STENCIL_REF);
- PY_DICT_ADD_INT(GL_STENCIL_TEST);
- PY_DICT_ADD_INT(GL_STENCIL_VALUE_MASK);
- PY_DICT_ADD_INT(GL_STENCIL_WRITEMASK);
- PY_DICT_ADD_INT(GL_STEREO);
- PY_DICT_ADD_INT(GL_SUBPIXEL_BITS);
- PY_DICT_ADD_INT(GL_TEXTURE);
- PY_DICT_ADD_INT(GL_TEXTURE_1D);
- PY_DICT_ADD_INT(GL_TEXTURE_2D);
- PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D);
- PY_DICT_ADD_INT(GL_TEXTURE_BLUE_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_BORDER_COLOR);
- PY_DICT_ADD_INT(GL_TEXTURE_GREEN_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_HEIGHT);
- PY_DICT_ADD_INT(GL_TEXTURE_INTERNAL_FORMAT);
- PY_DICT_ADD_INT(GL_TEXTURE_MAG_FILTER);
- PY_DICT_ADD_INT(GL_TEXTURE_MIN_FILTER);
- PY_DICT_ADD_INT(GL_TEXTURE_RED_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_WIDTH);
- PY_DICT_ADD_INT(GL_TEXTURE_WRAP_S);
- PY_DICT_ADD_INT(GL_TEXTURE_WRAP_T);
- PY_DICT_ADD_INT(GL_TRIANGLES);
- PY_DICT_ADD_INT(GL_TRIANGLE_FAN);
- PY_DICT_ADD_INT(GL_TRIANGLE_STRIP);
- PY_DICT_ADD_INT(GL_TRUE);
- PY_DICT_ADD_INT(GL_UNPACK_ALIGNMENT);
- PY_DICT_ADD_INT(GL_UNPACK_LSB_FIRST);
- PY_DICT_ADD_INT(GL_UNPACK_ROW_LENGTH);
- PY_DICT_ADD_INT(GL_UNPACK_SKIP_PIXELS);
- PY_DICT_ADD_INT(GL_UNPACK_SKIP_ROWS);
- PY_DICT_ADD_INT(GL_UNPACK_SWAP_BYTES);
- PY_DICT_ADD_INT(GL_UNSIGNED_BYTE);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT);
- PY_DICT_ADD_INT(GL_VENDOR);
- PY_DICT_ADD_INT(GL_VERSION);
- PY_DICT_ADD_INT(GL_VIEWPORT);
- PY_DICT_ADD_INT(GL_XOR);
- PY_DICT_ADD_INT(GL_ZERO);
- }
-
+ PY_DICT_ADD_INT(GL_ALPHA);
+ PY_DICT_ADD_INT(GL_ALWAYS);
+ PY_DICT_ADD_INT(GL_AND);
+ PY_DICT_ADD_INT(GL_AND_INVERTED);
+ PY_DICT_ADD_INT(GL_AND_REVERSE);
+ PY_DICT_ADD_INT(GL_BACK);
+ PY_DICT_ADD_INT(GL_BACK_LEFT);
+ PY_DICT_ADD_INT(GL_BACK_RIGHT);
+ PY_DICT_ADD_INT(GL_BLEND);
+ PY_DICT_ADD_INT(GL_BLEND_DST);
+ PY_DICT_ADD_INT(GL_BLEND_SRC);
+ PY_DICT_ADD_INT(GL_BLUE);
+ PY_DICT_ADD_INT(GL_BYTE);
+ PY_DICT_ADD_INT(GL_CCW);
+ PY_DICT_ADD_INT(GL_CLEAR);
+ PY_DICT_ADD_INT(GL_COLOR);
+ PY_DICT_ADD_INT(GL_COLOR_BUFFER_BIT);
+ PY_DICT_ADD_INT(GL_COLOR_CLEAR_VALUE);
+ PY_DICT_ADD_INT(GL_COLOR_LOGIC_OP);
+ PY_DICT_ADD_INT(GL_COLOR_WRITEMASK);
+ PY_DICT_ADD_INT(GL_COPY);
+ PY_DICT_ADD_INT(GL_COPY_INVERTED);
+ PY_DICT_ADD_INT(GL_CULL_FACE);
+ PY_DICT_ADD_INT(GL_CULL_FACE_MODE);
+ PY_DICT_ADD_INT(GL_CW);
+ PY_DICT_ADD_INT(GL_DECR);
+ PY_DICT_ADD_INT(GL_DEPTH);
+ PY_DICT_ADD_INT(GL_DEPTH_BUFFER_BIT);
+ PY_DICT_ADD_INT(GL_DEPTH_CLEAR_VALUE);
+ PY_DICT_ADD_INT(GL_DEPTH_COMPONENT);
+ PY_DICT_ADD_INT(GL_DEPTH_FUNC);
+ PY_DICT_ADD_INT(GL_DEPTH_RANGE);
+ PY_DICT_ADD_INT(GL_DEPTH_TEST);
+ PY_DICT_ADD_INT(GL_DEPTH_WRITEMASK);
+ PY_DICT_ADD_INT(GL_DITHER);
+ PY_DICT_ADD_INT(GL_DONT_CARE);
+ PY_DICT_ADD_INT(GL_DOUBLE);
+ PY_DICT_ADD_INT(GL_DOUBLEBUFFER);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER);
+ PY_DICT_ADD_INT(GL_DST_ALPHA);
+ PY_DICT_ADD_INT(GL_DST_COLOR);
+ PY_DICT_ADD_INT(GL_EQUAL);
+ PY_DICT_ADD_INT(GL_EQUIV);
+ PY_DICT_ADD_INT(GL_EXTENSIONS);
+ PY_DICT_ADD_INT(GL_FALSE);
+ PY_DICT_ADD_INT(GL_FASTEST);
+ PY_DICT_ADD_INT(GL_FILL);
+ PY_DICT_ADD_INT(GL_FLOAT);
+ PY_DICT_ADD_INT(GL_FRONT);
+ PY_DICT_ADD_INT(GL_FRONT_AND_BACK);
+ PY_DICT_ADD_INT(GL_FRONT_FACE);
+ PY_DICT_ADD_INT(GL_FRONT_LEFT);
+ PY_DICT_ADD_INT(GL_FRONT_RIGHT);
+ PY_DICT_ADD_INT(GL_GEQUAL);
+ PY_DICT_ADD_INT(GL_GREATER);
+ PY_DICT_ADD_INT(GL_GREEN);
+ PY_DICT_ADD_INT(GL_INCR);
+ PY_DICT_ADD_INT(GL_INT);
+ PY_DICT_ADD_INT(GL_INVALID_ENUM);
+ PY_DICT_ADD_INT(GL_INVALID_OPERATION);
+ PY_DICT_ADD_INT(GL_INVALID_VALUE);
+ PY_DICT_ADD_INT(GL_INVERT);
+ PY_DICT_ADD_INT(GL_KEEP);
+ PY_DICT_ADD_INT(GL_LEFT);
+ PY_DICT_ADD_INT(GL_LEQUAL);
+ PY_DICT_ADD_INT(GL_LESS);
+ PY_DICT_ADD_INT(GL_LINE);
+ PY_DICT_ADD_INT(GL_LINEAR);
+ PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_LINEAR);
+ PY_DICT_ADD_INT(GL_LINEAR_MIPMAP_NEAREST);
+ PY_DICT_ADD_INT(GL_LINES);
+ PY_DICT_ADD_INT(GL_LINE_LOOP);
+ PY_DICT_ADD_INT(GL_LINE_SMOOTH);
+ PY_DICT_ADD_INT(GL_LINE_SMOOTH_HINT);
+ PY_DICT_ADD_INT(GL_LINE_STRIP);
+ PY_DICT_ADD_INT(GL_LINE_WIDTH);
+ PY_DICT_ADD_INT(GL_LINE_WIDTH_GRANULARITY);
+ PY_DICT_ADD_INT(GL_LINE_WIDTH_RANGE);
+ PY_DICT_ADD_INT(GL_LOGIC_OP_MODE);
+ PY_DICT_ADD_INT(GL_MAX_TEXTURE_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_VIEWPORT_DIMS);
+ PY_DICT_ADD_INT(GL_NAND);
+ PY_DICT_ADD_INT(GL_NEAREST);
+ PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_LINEAR);
+ PY_DICT_ADD_INT(GL_NEAREST_MIPMAP_NEAREST);
+ PY_DICT_ADD_INT(GL_NEVER);
+ PY_DICT_ADD_INT(GL_NICEST);
+ PY_DICT_ADD_INT(GL_NONE);
+ PY_DICT_ADD_INT(GL_NOOP);
+ PY_DICT_ADD_INT(GL_NOR);
+ PY_DICT_ADD_INT(GL_NOTEQUAL);
+ PY_DICT_ADD_INT(GL_NO_ERROR);
+ PY_DICT_ADD_INT(GL_ONE);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_DST_ALPHA);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_DST_COLOR);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_ALPHA);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_SRC_COLOR);
+ PY_DICT_ADD_INT(GL_OR);
+ PY_DICT_ADD_INT(GL_OR_INVERTED);
+ PY_DICT_ADD_INT(GL_OR_REVERSE);
+ PY_DICT_ADD_INT(GL_OUT_OF_MEMORY);
+ PY_DICT_ADD_INT(GL_PACK_ALIGNMENT);
+ PY_DICT_ADD_INT(GL_PACK_LSB_FIRST);
+ PY_DICT_ADD_INT(GL_PACK_ROW_LENGTH);
+ PY_DICT_ADD_INT(GL_PACK_SKIP_PIXELS);
+ PY_DICT_ADD_INT(GL_PACK_SKIP_ROWS);
+ PY_DICT_ADD_INT(GL_PACK_SWAP_BYTES);
+ PY_DICT_ADD_INT(GL_POINT);
+ PY_DICT_ADD_INT(GL_POINTS);
+ PY_DICT_ADD_INT(GL_POINT_SIZE);
+ PY_DICT_ADD_INT(GL_POLYGON_MODE);
+ PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FACTOR);
+ PY_DICT_ADD_INT(GL_POLYGON_OFFSET_FILL);
+ PY_DICT_ADD_INT(GL_POLYGON_OFFSET_LINE);
+ PY_DICT_ADD_INT(GL_POLYGON_OFFSET_POINT);
+ PY_DICT_ADD_INT(GL_POLYGON_OFFSET_UNITS);
+ PY_DICT_ADD_INT(GL_POLYGON_SMOOTH);
+ PY_DICT_ADD_INT(GL_POLYGON_SMOOTH_HINT);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D);
+ PY_DICT_ADD_INT(GL_R3_G3_B2);
+ PY_DICT_ADD_INT(GL_READ_BUFFER);
+ PY_DICT_ADD_INT(GL_RED);
+ PY_DICT_ADD_INT(GL_RENDERER);
+ PY_DICT_ADD_INT(GL_REPEAT);
+ PY_DICT_ADD_INT(GL_REPLACE);
+ PY_DICT_ADD_INT(GL_RGB);
+ PY_DICT_ADD_INT(GL_RGB10);
+ PY_DICT_ADD_INT(GL_RGB10_A2);
+ PY_DICT_ADD_INT(GL_RGB12);
+ PY_DICT_ADD_INT(GL_RGB16);
+ PY_DICT_ADD_INT(GL_RGB4);
+ PY_DICT_ADD_INT(GL_RGB5);
+ PY_DICT_ADD_INT(GL_RGB5_A1);
+ PY_DICT_ADD_INT(GL_RGB8);
+ PY_DICT_ADD_INT(GL_RGBA);
+ PY_DICT_ADD_INT(GL_RGBA12);
+ PY_DICT_ADD_INT(GL_RGBA16);
+ PY_DICT_ADD_INT(GL_RGBA2);
+ PY_DICT_ADD_INT(GL_RGBA4);
+ PY_DICT_ADD_INT(GL_RGBA8);
+ PY_DICT_ADD_INT(GL_RIGHT);
+ PY_DICT_ADD_INT(GL_SCISSOR_BOX);
+ PY_DICT_ADD_INT(GL_SCISSOR_TEST);
+ PY_DICT_ADD_INT(GL_SET);
+ PY_DICT_ADD_INT(GL_SHORT);
+ PY_DICT_ADD_INT(GL_SRC_ALPHA);
+ PY_DICT_ADD_INT(GL_SRC_ALPHA_SATURATE);
+ PY_DICT_ADD_INT(GL_SRC_COLOR);
+ PY_DICT_ADD_INT(GL_STENCIL);
+ PY_DICT_ADD_INT(GL_STENCIL_BUFFER_BIT);
+ PY_DICT_ADD_INT(GL_STENCIL_CLEAR_VALUE);
+ PY_DICT_ADD_INT(GL_STENCIL_FAIL);
+ PY_DICT_ADD_INT(GL_STENCIL_FUNC);
+ PY_DICT_ADD_INT(GL_STENCIL_INDEX);
+ PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_FAIL);
+ PY_DICT_ADD_INT(GL_STENCIL_PASS_DEPTH_PASS);
+ PY_DICT_ADD_INT(GL_STENCIL_REF);
+ PY_DICT_ADD_INT(GL_STENCIL_TEST);
+ PY_DICT_ADD_INT(GL_STENCIL_VALUE_MASK);
+ PY_DICT_ADD_INT(GL_STENCIL_WRITEMASK);
+ PY_DICT_ADD_INT(GL_STEREO);
+ PY_DICT_ADD_INT(GL_SUBPIXEL_BITS);
+ PY_DICT_ADD_INT(GL_TEXTURE);
+ PY_DICT_ADD_INT(GL_TEXTURE_1D);
+ PY_DICT_ADD_INT(GL_TEXTURE_2D);
+ PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D);
+ PY_DICT_ADD_INT(GL_TEXTURE_BLUE_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_BORDER_COLOR);
+ PY_DICT_ADD_INT(GL_TEXTURE_GREEN_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_HEIGHT);
+ PY_DICT_ADD_INT(GL_TEXTURE_INTERNAL_FORMAT);
+ PY_DICT_ADD_INT(GL_TEXTURE_MAG_FILTER);
+ PY_DICT_ADD_INT(GL_TEXTURE_MIN_FILTER);
+ PY_DICT_ADD_INT(GL_TEXTURE_RED_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_WIDTH);
+ PY_DICT_ADD_INT(GL_TEXTURE_WRAP_S);
+ PY_DICT_ADD_INT(GL_TEXTURE_WRAP_T);
+ PY_DICT_ADD_INT(GL_TRIANGLES);
+ PY_DICT_ADD_INT(GL_TRIANGLE_FAN);
+ PY_DICT_ADD_INT(GL_TRIANGLE_STRIP);
+ PY_DICT_ADD_INT(GL_TRUE);
+ PY_DICT_ADD_INT(GL_UNPACK_ALIGNMENT);
+ PY_DICT_ADD_INT(GL_UNPACK_LSB_FIRST);
+ PY_DICT_ADD_INT(GL_UNPACK_ROW_LENGTH);
+ PY_DICT_ADD_INT(GL_UNPACK_SKIP_PIXELS);
+ PY_DICT_ADD_INT(GL_UNPACK_SKIP_ROWS);
+ PY_DICT_ADD_INT(GL_UNPACK_SWAP_BYTES);
+ PY_DICT_ADD_INT(GL_UNSIGNED_BYTE);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT);
+ PY_DICT_ADD_INT(GL_VENDOR);
+ PY_DICT_ADD_INT(GL_VERSION);
+ PY_DICT_ADD_INT(GL_VIEWPORT);
+ PY_DICT_ADD_INT(GL_XOR);
+ PY_DICT_ADD_INT(GL_ZERO);
+}
+static void init_bgl_version_1_2_constants(PyObject *dict)
+{
/* GL_VERSION_1_2 */
- {
- PY_DICT_ADD_INT(GL_ALIASED_LINE_WIDTH_RANGE);
- PY_DICT_ADD_INT(GL_BGR);
- PY_DICT_ADD_INT(GL_BGRA);
- PY_DICT_ADD_INT(GL_CLAMP_TO_EDGE);
- PY_DICT_ADD_INT(GL_MAX_3D_TEXTURE_SIZE);
- PY_DICT_ADD_INT(GL_MAX_ELEMENTS_INDICES);
- PY_DICT_ADD_INT(GL_MAX_ELEMENTS_VERTICES);
- PY_DICT_ADD_INT(GL_PACK_IMAGE_HEIGHT);
- PY_DICT_ADD_INT(GL_PACK_SKIP_IMAGES);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_3D);
- PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
- PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_RANGE);
- PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_GRANULARITY);
- PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_RANGE);
- PY_DICT_ADD_INT(GL_TEXTURE_3D);
- PY_DICT_ADD_INT(GL_TEXTURE_BASE_LEVEL);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_3D);
- PY_DICT_ADD_INT(GL_TEXTURE_DEPTH);
- PY_DICT_ADD_INT(GL_TEXTURE_MAX_LEVEL);
- PY_DICT_ADD_INT(GL_TEXTURE_MAX_LOD);
- PY_DICT_ADD_INT(GL_TEXTURE_MIN_LOD);
- PY_DICT_ADD_INT(GL_TEXTURE_WRAP_R);
- PY_DICT_ADD_INT(GL_UNPACK_IMAGE_HEIGHT);
- PY_DICT_ADD_INT(GL_UNPACK_SKIP_IMAGES);
- PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_2_3_3_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_3_3_2);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_10_10_10_2);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_2_10_10_10_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_1_5_5_5_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_5_5_1);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5);
- PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5_REV);
- }
-
+ PY_DICT_ADD_INT(GL_ALIASED_LINE_WIDTH_RANGE);
+ PY_DICT_ADD_INT(GL_BGR);
+ PY_DICT_ADD_INT(GL_BGRA);
+ PY_DICT_ADD_INT(GL_CLAMP_TO_EDGE);
+ PY_DICT_ADD_INT(GL_MAX_3D_TEXTURE_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_ELEMENTS_INDICES);
+ PY_DICT_ADD_INT(GL_MAX_ELEMENTS_VERTICES);
+ PY_DICT_ADD_INT(GL_PACK_IMAGE_HEIGHT);
+ PY_DICT_ADD_INT(GL_PACK_SKIP_IMAGES);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_3D);
+ PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_GRANULARITY);
+ PY_DICT_ADD_INT(GL_SMOOTH_LINE_WIDTH_RANGE);
+ PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_GRANULARITY);
+ PY_DICT_ADD_INT(GL_SMOOTH_POINT_SIZE_RANGE);
+ PY_DICT_ADD_INT(GL_TEXTURE_3D);
+ PY_DICT_ADD_INT(GL_TEXTURE_BASE_LEVEL);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_3D);
+ PY_DICT_ADD_INT(GL_TEXTURE_DEPTH);
+ PY_DICT_ADD_INT(GL_TEXTURE_MAX_LEVEL);
+ PY_DICT_ADD_INT(GL_TEXTURE_MAX_LOD);
+ PY_DICT_ADD_INT(GL_TEXTURE_MIN_LOD);
+ PY_DICT_ADD_INT(GL_TEXTURE_WRAP_R);
+ PY_DICT_ADD_INT(GL_UNPACK_IMAGE_HEIGHT);
+ PY_DICT_ADD_INT(GL_UNPACK_SKIP_IMAGES);
+ PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_2_3_3_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_BYTE_3_3_2);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_10_10_10_2);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_2_10_10_10_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_8_8_8_8_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_1_5_5_5_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_4_4_4_4_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_5_5_1);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5);
+ PY_DICT_ADD_INT(GL_UNSIGNED_SHORT_5_6_5_REV);
+}
+static void init_bgl_version_1_3_constants(PyObject *dict)
+{
/* GL_VERSION_1_3 */
- {
- PY_DICT_ADD_INT(GL_ACTIVE_TEXTURE);
- PY_DICT_ADD_INT(GL_CLAMP_TO_BORDER);
- PY_DICT_ADD_INT(GL_COMPRESSED_RGB);
- PY_DICT_ADD_INT(GL_COMPRESSED_RGBA);
- PY_DICT_ADD_INT(GL_COMPRESSED_TEXTURE_FORMATS);
- PY_DICT_ADD_INT(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
- PY_DICT_ADD_INT(GL_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_CUBE_MAP);
- PY_DICT_ADD_INT(GL_SAMPLES);
- PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_COVERAGE);
- PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_ONE);
- PY_DICT_ADD_INT(GL_SAMPLE_BUFFERS);
- PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE);
- PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_INVERT);
- PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_VALUE);
- PY_DICT_ADD_INT(GL_TEXTURE0);
- PY_DICT_ADD_INT(GL_TEXTURE1);
- PY_DICT_ADD_INT(GL_TEXTURE10);
- PY_DICT_ADD_INT(GL_TEXTURE11);
- PY_DICT_ADD_INT(GL_TEXTURE12);
- PY_DICT_ADD_INT(GL_TEXTURE13);
- PY_DICT_ADD_INT(GL_TEXTURE14);
- PY_DICT_ADD_INT(GL_TEXTURE15);
- PY_DICT_ADD_INT(GL_TEXTURE16);
- PY_DICT_ADD_INT(GL_TEXTURE17);
- PY_DICT_ADD_INT(GL_TEXTURE18);
- PY_DICT_ADD_INT(GL_TEXTURE19);
- PY_DICT_ADD_INT(GL_TEXTURE2);
- PY_DICT_ADD_INT(GL_TEXTURE20);
- PY_DICT_ADD_INT(GL_TEXTURE21);
- PY_DICT_ADD_INT(GL_TEXTURE22);
- PY_DICT_ADD_INT(GL_TEXTURE23);
- PY_DICT_ADD_INT(GL_TEXTURE24);
- PY_DICT_ADD_INT(GL_TEXTURE25);
- PY_DICT_ADD_INT(GL_TEXTURE26);
- PY_DICT_ADD_INT(GL_TEXTURE27);
- PY_DICT_ADD_INT(GL_TEXTURE28);
- PY_DICT_ADD_INT(GL_TEXTURE29);
- PY_DICT_ADD_INT(GL_TEXTURE3);
- PY_DICT_ADD_INT(GL_TEXTURE30);
- PY_DICT_ADD_INT(GL_TEXTURE31);
- PY_DICT_ADD_INT(GL_TEXTURE4);
- PY_DICT_ADD_INT(GL_TEXTURE5);
- PY_DICT_ADD_INT(GL_TEXTURE6);
- PY_DICT_ADD_INT(GL_TEXTURE7);
- PY_DICT_ADD_INT(GL_TEXTURE8);
- PY_DICT_ADD_INT(GL_TEXTURE9);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_CUBE_MAP);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED_IMAGE_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSION_HINT);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
- }
-
+ PY_DICT_ADD_INT(GL_ACTIVE_TEXTURE);
+ PY_DICT_ADD_INT(GL_CLAMP_TO_BORDER);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RGB);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RGBA);
+ PY_DICT_ADD_INT(GL_COMPRESSED_TEXTURE_FORMATS);
+ PY_DICT_ADD_INT(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
+ PY_DICT_ADD_INT(GL_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_NUM_COMPRESSED_TEXTURE_FORMATS);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_CUBE_MAP);
+ PY_DICT_ADD_INT(GL_SAMPLES);
+ PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_COVERAGE);
+ PY_DICT_ADD_INT(GL_SAMPLE_ALPHA_TO_ONE);
+ PY_DICT_ADD_INT(GL_SAMPLE_BUFFERS);
+ PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE);
+ PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_INVERT);
+ PY_DICT_ADD_INT(GL_SAMPLE_COVERAGE_VALUE);
+ PY_DICT_ADD_INT(GL_TEXTURE0);
+ PY_DICT_ADD_INT(GL_TEXTURE1);
+ PY_DICT_ADD_INT(GL_TEXTURE10);
+ PY_DICT_ADD_INT(GL_TEXTURE11);
+ PY_DICT_ADD_INT(GL_TEXTURE12);
+ PY_DICT_ADD_INT(GL_TEXTURE13);
+ PY_DICT_ADD_INT(GL_TEXTURE14);
+ PY_DICT_ADD_INT(GL_TEXTURE15);
+ PY_DICT_ADD_INT(GL_TEXTURE16);
+ PY_DICT_ADD_INT(GL_TEXTURE17);
+ PY_DICT_ADD_INT(GL_TEXTURE18);
+ PY_DICT_ADD_INT(GL_TEXTURE19);
+ PY_DICT_ADD_INT(GL_TEXTURE2);
+ PY_DICT_ADD_INT(GL_TEXTURE20);
+ PY_DICT_ADD_INT(GL_TEXTURE21);
+ PY_DICT_ADD_INT(GL_TEXTURE22);
+ PY_DICT_ADD_INT(GL_TEXTURE23);
+ PY_DICT_ADD_INT(GL_TEXTURE24);
+ PY_DICT_ADD_INT(GL_TEXTURE25);
+ PY_DICT_ADD_INT(GL_TEXTURE26);
+ PY_DICT_ADD_INT(GL_TEXTURE27);
+ PY_DICT_ADD_INT(GL_TEXTURE28);
+ PY_DICT_ADD_INT(GL_TEXTURE29);
+ PY_DICT_ADD_INT(GL_TEXTURE3);
+ PY_DICT_ADD_INT(GL_TEXTURE30);
+ PY_DICT_ADD_INT(GL_TEXTURE31);
+ PY_DICT_ADD_INT(GL_TEXTURE4);
+ PY_DICT_ADD_INT(GL_TEXTURE5);
+ PY_DICT_ADD_INT(GL_TEXTURE6);
+ PY_DICT_ADD_INT(GL_TEXTURE7);
+ PY_DICT_ADD_INT(GL_TEXTURE8);
+ PY_DICT_ADD_INT(GL_TEXTURE9);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_CUBE_MAP);
+ PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED);
+ PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSED_IMAGE_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_COMPRESSION_HINT);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_X);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Y);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_POSITIVE_Z);
+}
+static void init_bgl_version_1_4_constants(PyObject *dict)
+{
/* GL_VERSION_1_4 */
- {
- PY_DICT_ADD_INT(GL_BLEND_DST_ALPHA);
- PY_DICT_ADD_INT(GL_BLEND_DST_RGB);
- PY_DICT_ADD_INT(GL_BLEND_SRC_ALPHA);
- PY_DICT_ADD_INT(GL_BLEND_SRC_RGB);
- PY_DICT_ADD_INT(GL_CONSTANT_ALPHA);
- PY_DICT_ADD_INT(GL_CONSTANT_COLOR);
- PY_DICT_ADD_INT(GL_DECR_WRAP);
- PY_DICT_ADD_INT(GL_DEPTH_COMPONENT16);
- PY_DICT_ADD_INT(GL_DEPTH_COMPONENT24);
- PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32);
- PY_DICT_ADD_INT(GL_FUNC_ADD);
- PY_DICT_ADD_INT(GL_FUNC_REVERSE_SUBTRACT);
- PY_DICT_ADD_INT(GL_FUNC_SUBTRACT);
- PY_DICT_ADD_INT(GL_INCR_WRAP);
- PY_DICT_ADD_INT(GL_MAX);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_LOD_BIAS);
- PY_DICT_ADD_INT(GL_MIN);
- PY_DICT_ADD_INT(GL_MIRRORED_REPEAT);
- PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_ALPHA);
- PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_COLOR);
- PY_DICT_ADD_INT(GL_POINT_FADE_THRESHOLD_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_FUNC);
- PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_MODE);
- PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_LOD_BIAS);
- }
-
+ PY_DICT_ADD_INT(GL_BLEND_DST_ALPHA);
+ PY_DICT_ADD_INT(GL_BLEND_DST_RGB);
+ PY_DICT_ADD_INT(GL_BLEND_SRC_ALPHA);
+ PY_DICT_ADD_INT(GL_BLEND_SRC_RGB);
+ PY_DICT_ADD_INT(GL_CONSTANT_ALPHA);
+ PY_DICT_ADD_INT(GL_CONSTANT_COLOR);
+ PY_DICT_ADD_INT(GL_DECR_WRAP);
+ PY_DICT_ADD_INT(GL_DEPTH_COMPONENT16);
+ PY_DICT_ADD_INT(GL_DEPTH_COMPONENT24);
+ PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32);
+ PY_DICT_ADD_INT(GL_FUNC_ADD);
+ PY_DICT_ADD_INT(GL_FUNC_REVERSE_SUBTRACT);
+ PY_DICT_ADD_INT(GL_FUNC_SUBTRACT);
+ PY_DICT_ADD_INT(GL_INCR_WRAP);
+ PY_DICT_ADD_INT(GL_MAX);
+ PY_DICT_ADD_INT(GL_MAX_TEXTURE_LOD_BIAS);
+ PY_DICT_ADD_INT(GL_MIN);
+ PY_DICT_ADD_INT(GL_MIRRORED_REPEAT);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_ALPHA);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_CONSTANT_COLOR);
+ PY_DICT_ADD_INT(GL_POINT_FADE_THRESHOLD_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_FUNC);
+ PY_DICT_ADD_INT(GL_TEXTURE_COMPARE_MODE);
+ PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_LOD_BIAS);
+}
+static void init_bgl_version_1_5_constants(PyObject *dict)
+{
/* GL_VERSION_1_5 */
- {
- PY_DICT_ADD_INT(GL_ARRAY_BUFFER);
- PY_DICT_ADD_INT(GL_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_BUFFER_ACCESS);
- PY_DICT_ADD_INT(GL_BUFFER_MAPPED);
- PY_DICT_ADD_INT(GL_BUFFER_MAP_POINTER);
- PY_DICT_ADD_INT(GL_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_BUFFER_USAGE);
- PY_DICT_ADD_INT(GL_CURRENT_QUERY);
- PY_DICT_ADD_INT(GL_DYNAMIC_COPY);
- PY_DICT_ADD_INT(GL_DYNAMIC_DRAW);
- PY_DICT_ADD_INT(GL_DYNAMIC_READ);
- PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER);
- PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_QUERY_COUNTER_BITS);
- PY_DICT_ADD_INT(GL_QUERY_RESULT);
- PY_DICT_ADD_INT(GL_QUERY_RESULT_AVAILABLE);
- PY_DICT_ADD_INT(GL_READ_ONLY);
- PY_DICT_ADD_INT(GL_READ_WRITE);
- PY_DICT_ADD_INT(GL_SAMPLES_PASSED);
- PY_DICT_ADD_INT(GL_STATIC_COPY);
- PY_DICT_ADD_INT(GL_STATIC_DRAW);
- PY_DICT_ADD_INT(GL_STATIC_READ);
- PY_DICT_ADD_INT(GL_STREAM_COPY);
- PY_DICT_ADD_INT(GL_STREAM_DRAW);
- PY_DICT_ADD_INT(GL_STREAM_READ);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_WRITE_ONLY);
- }
-
+ PY_DICT_ADD_INT(GL_ARRAY_BUFFER);
+ PY_DICT_ADD_INT(GL_ARRAY_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_BUFFER_ACCESS);
+ PY_DICT_ADD_INT(GL_BUFFER_MAPPED);
+ PY_DICT_ADD_INT(GL_BUFFER_MAP_POINTER);
+ PY_DICT_ADD_INT(GL_BUFFER_SIZE);
+ PY_DICT_ADD_INT(GL_BUFFER_USAGE);
+ PY_DICT_ADD_INT(GL_CURRENT_QUERY);
+ PY_DICT_ADD_INT(GL_DYNAMIC_COPY);
+ PY_DICT_ADD_INT(GL_DYNAMIC_DRAW);
+ PY_DICT_ADD_INT(GL_DYNAMIC_READ);
+ PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER);
+ PY_DICT_ADD_INT(GL_ELEMENT_ARRAY_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_QUERY_COUNTER_BITS);
+ PY_DICT_ADD_INT(GL_QUERY_RESULT);
+ PY_DICT_ADD_INT(GL_QUERY_RESULT_AVAILABLE);
+ PY_DICT_ADD_INT(GL_READ_ONLY);
+ PY_DICT_ADD_INT(GL_READ_WRITE);
+ PY_DICT_ADD_INT(GL_SAMPLES_PASSED);
+ PY_DICT_ADD_INT(GL_STATIC_COPY);
+ PY_DICT_ADD_INT(GL_STATIC_DRAW);
+ PY_DICT_ADD_INT(GL_STATIC_READ);
+ PY_DICT_ADD_INT(GL_STREAM_COPY);
+ PY_DICT_ADD_INT(GL_STREAM_DRAW);
+ PY_DICT_ADD_INT(GL_STREAM_READ);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_WRITE_ONLY);
+}
+static void init_bgl_version_2_0_constants(PyObject *dict)
+{
/* GL_VERSION_2_0 */
- {
- PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTES);
- PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
- PY_DICT_ADD_INT(GL_ACTIVE_UNIFORMS);
- PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_MAX_LENGTH);
- PY_DICT_ADD_INT(GL_ATTACHED_SHADERS);
- PY_DICT_ADD_INT(GL_BLEND_EQUATION_ALPHA);
- PY_DICT_ADD_INT(GL_BLEND_EQUATION_RGB);
- PY_DICT_ADD_INT(GL_BOOL);
- PY_DICT_ADD_INT(GL_BOOL_VEC2);
- PY_DICT_ADD_INT(GL_BOOL_VEC3);
- PY_DICT_ADD_INT(GL_BOOL_VEC4);
- PY_DICT_ADD_INT(GL_COMPILE_STATUS);
- PY_DICT_ADD_INT(GL_CURRENT_PROGRAM);
- PY_DICT_ADD_INT(GL_CURRENT_VERTEX_ATTRIB);
- PY_DICT_ADD_INT(GL_DELETE_STATUS);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER0);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER1);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER10);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER11);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER12);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER13);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER14);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER15);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER2);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER3);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER4);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER5);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER6);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER7);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER8);
- PY_DICT_ADD_INT(GL_DRAW_BUFFER9);
- PY_DICT_ADD_INT(GL_FLOAT_MAT2);
- PY_DICT_ADD_INT(GL_FLOAT_MAT3);
- PY_DICT_ADD_INT(GL_FLOAT_MAT4);
- PY_DICT_ADD_INT(GL_FLOAT_VEC2);
- PY_DICT_ADD_INT(GL_FLOAT_VEC3);
- PY_DICT_ADD_INT(GL_FLOAT_VEC4);
- PY_DICT_ADD_INT(GL_FRAGMENT_SHADER);
- PY_DICT_ADD_INT(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
- PY_DICT_ADD_INT(GL_INFO_LOG_LENGTH);
- PY_DICT_ADD_INT(GL_INT_VEC2);
- PY_DICT_ADD_INT(GL_INT_VEC3);
- PY_DICT_ADD_INT(GL_INT_VEC4);
- PY_DICT_ADD_INT(GL_LINK_STATUS);
- PY_DICT_ADD_INT(GL_LOWER_LEFT);
- PY_DICT_ADD_INT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
- PY_DICT_ADD_INT(GL_MAX_DRAW_BUFFERS);
- PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_IMAGE_UNITS);
- PY_DICT_ADD_INT(GL_MAX_VARYING_FLOATS);
- PY_DICT_ADD_INT(GL_MAX_VERTEX_ATTRIBS);
- PY_DICT_ADD_INT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
- PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_POINT_SPRITE_COORD_ORIGIN);
- PY_DICT_ADD_INT(GL_SAMPLER_1D);
- PY_DICT_ADD_INT(GL_SAMPLER_1D_SHADOW);
- PY_DICT_ADD_INT(GL_SAMPLER_2D);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_SHADOW);
- PY_DICT_ADD_INT(GL_SAMPLER_3D);
- PY_DICT_ADD_INT(GL_SAMPLER_CUBE);
- PY_DICT_ADD_INT(GL_SHADER_SOURCE_LENGTH);
- PY_DICT_ADD_INT(GL_SHADER_TYPE);
- PY_DICT_ADD_INT(GL_SHADING_LANGUAGE_VERSION);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_FAIL);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_FUNC);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_PASS);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_REF);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_VALUE_MASK);
- PY_DICT_ADD_INT(GL_STENCIL_BACK_WRITEMASK);
- PY_DICT_ADD_INT(GL_UPPER_LEFT);
- PY_DICT_ADD_INT(GL_VALIDATE_STATUS);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_ENABLED);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_POINTER);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_SIZE);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_TYPE);
- PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_POINT_SIZE);
- PY_DICT_ADD_INT(GL_VERTEX_SHADER);
- }
-
+ PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTES);
+ PY_DICT_ADD_INT(GL_ACTIVE_ATTRIBUTE_MAX_LENGTH);
+ PY_DICT_ADD_INT(GL_ACTIVE_UNIFORMS);
+ PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_MAX_LENGTH);
+ PY_DICT_ADD_INT(GL_ATTACHED_SHADERS);
+ PY_DICT_ADD_INT(GL_BLEND_EQUATION_ALPHA);
+ PY_DICT_ADD_INT(GL_BLEND_EQUATION_RGB);
+ PY_DICT_ADD_INT(GL_BOOL);
+ PY_DICT_ADD_INT(GL_BOOL_VEC2);
+ PY_DICT_ADD_INT(GL_BOOL_VEC3);
+ PY_DICT_ADD_INT(GL_BOOL_VEC4);
+ PY_DICT_ADD_INT(GL_COMPILE_STATUS);
+ PY_DICT_ADD_INT(GL_CURRENT_PROGRAM);
+ PY_DICT_ADD_INT(GL_CURRENT_VERTEX_ATTRIB);
+ PY_DICT_ADD_INT(GL_DELETE_STATUS);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER0);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER1);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER10);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER11);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER12);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER13);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER14);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER15);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER2);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER3);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER4);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER5);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER6);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER7);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER8);
+ PY_DICT_ADD_INT(GL_DRAW_BUFFER9);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT2);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT3);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT4);
+ PY_DICT_ADD_INT(GL_FLOAT_VEC2);
+ PY_DICT_ADD_INT(GL_FLOAT_VEC3);
+ PY_DICT_ADD_INT(GL_FLOAT_VEC4);
+ PY_DICT_ADD_INT(GL_FRAGMENT_SHADER);
+ PY_DICT_ADD_INT(GL_FRAGMENT_SHADER_DERIVATIVE_HINT);
+ PY_DICT_ADD_INT(GL_INFO_LOG_LENGTH);
+ PY_DICT_ADD_INT(GL_INT_VEC2);
+ PY_DICT_ADD_INT(GL_INT_VEC3);
+ PY_DICT_ADD_INT(GL_INT_VEC4);
+ PY_DICT_ADD_INT(GL_LINK_STATUS);
+ PY_DICT_ADD_INT(GL_LOWER_LEFT);
+ PY_DICT_ADD_INT(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ PY_DICT_ADD_INT(GL_MAX_DRAW_BUFFERS);
+ PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_TEXTURE_IMAGE_UNITS);
+ PY_DICT_ADD_INT(GL_MAX_VARYING_FLOATS);
+ PY_DICT_ADD_INT(GL_MAX_VERTEX_ATTRIBS);
+ PY_DICT_ADD_INT(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_POINT_SPRITE_COORD_ORIGIN);
+ PY_DICT_ADD_INT(GL_SAMPLER_1D);
+ PY_DICT_ADD_INT(GL_SAMPLER_1D_SHADOW);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_SHADOW);
+ PY_DICT_ADD_INT(GL_SAMPLER_3D);
+ PY_DICT_ADD_INT(GL_SAMPLER_CUBE);
+ PY_DICT_ADD_INT(GL_SHADER_SOURCE_LENGTH);
+ PY_DICT_ADD_INT(GL_SHADER_TYPE);
+ PY_DICT_ADD_INT(GL_SHADING_LANGUAGE_VERSION);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_FAIL);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_FUNC);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_FAIL);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_PASS_DEPTH_PASS);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_REF);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_VALUE_MASK);
+ PY_DICT_ADD_INT(GL_STENCIL_BACK_WRITEMASK);
+ PY_DICT_ADD_INT(GL_UPPER_LEFT);
+ PY_DICT_ADD_INT(GL_VALIDATE_STATUS);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_ENABLED);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_POINTER);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_SIZE);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_STRIDE);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_TYPE);
+ PY_DICT_ADD_INT(GL_VERTEX_PROGRAM_POINT_SIZE);
+ PY_DICT_ADD_INT(GL_VERTEX_SHADER);
+}
+static void init_bgl_version_2_1_constants(PyObject *dict)
+{
/* GL_VERSION_2_1 */
- {
- PY_DICT_ADD_INT(GL_COMPRESSED_SRGB);
- PY_DICT_ADD_INT(GL_COMPRESSED_SRGB_ALPHA);
- PY_DICT_ADD_INT(GL_FLOAT_MAT2x3);
- PY_DICT_ADD_INT(GL_FLOAT_MAT2x4);
- PY_DICT_ADD_INT(GL_FLOAT_MAT3x2);
- PY_DICT_ADD_INT(GL_FLOAT_MAT3x4);
- PY_DICT_ADD_INT(GL_FLOAT_MAT4x2);
- PY_DICT_ADD_INT(GL_FLOAT_MAT4x3);
- PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER);
- PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER);
- PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_SRGB);
- PY_DICT_ADD_INT(GL_SRGB8);
- PY_DICT_ADD_INT(GL_SRGB8_ALPHA8);
- PY_DICT_ADD_INT(GL_SRGB_ALPHA);
- }
-
+ PY_DICT_ADD_INT(GL_COMPRESSED_SRGB);
+ PY_DICT_ADD_INT(GL_COMPRESSED_SRGB_ALPHA);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT2x3);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT2x4);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT3x2);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT3x4);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT4x2);
+ PY_DICT_ADD_INT(GL_FLOAT_MAT4x3);
+ PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER);
+ PY_DICT_ADD_INT(GL_PIXEL_PACK_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER);
+ PY_DICT_ADD_INT(GL_PIXEL_UNPACK_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_SRGB);
+ PY_DICT_ADD_INT(GL_SRGB8);
+ PY_DICT_ADD_INT(GL_SRGB8_ALPHA8);
+ PY_DICT_ADD_INT(GL_SRGB_ALPHA);
+}
+static void init_bgl_version_3_0_constants(PyObject *dict)
+{
/* GL_VERSION_3_0 */
- {
- PY_DICT_ADD_INT(GL_BGRA_INTEGER);
- PY_DICT_ADD_INT(GL_BGR_INTEGER);
- PY_DICT_ADD_INT(GL_BLUE_INTEGER);
- PY_DICT_ADD_INT(GL_BUFFER_ACCESS_FLAGS);
- PY_DICT_ADD_INT(GL_BUFFER_MAP_LENGTH);
- PY_DICT_ADD_INT(GL_BUFFER_MAP_OFFSET);
- PY_DICT_ADD_INT(GL_CLAMP_READ_COLOR);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE0);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE1);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE2);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE3);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE4);
- PY_DICT_ADD_INT(GL_CLIP_DISTANCE5);
+ PY_DICT_ADD_INT(GL_BGRA_INTEGER);
+ PY_DICT_ADD_INT(GL_BGR_INTEGER);
+ PY_DICT_ADD_INT(GL_BLUE_INTEGER);
+ PY_DICT_ADD_INT(GL_BUFFER_ACCESS_FLAGS);
+ PY_DICT_ADD_INT(GL_BUFFER_MAP_LENGTH);
+ PY_DICT_ADD_INT(GL_BUFFER_MAP_OFFSET);
+ PY_DICT_ADD_INT(GL_CLAMP_READ_COLOR);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE0);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE1);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE2);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE3);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE4);
+ PY_DICT_ADD_INT(GL_CLIP_DISTANCE5);
#if 0
PY_DICT_ADD_INT(GL_CLIP_DISTANCE6);
PY_DICT_ADD_INT(GL_CLIP_DISTANCE7);
#endif
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT0);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT1);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT2);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT3);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT4);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT5);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT6);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT7);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT8);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT9);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT10);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT11);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT12);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT13);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT14);
- PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT15);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT0);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT1);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT2);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT3);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT4);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT5);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT6);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT7);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT8);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT9);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT10);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT11);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT12);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT13);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT14);
+ PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT15);
#if 0
PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT16);
PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT17);
@@ -2267,346 +2248,384 @@ PyObject *BPyInit_bgl(void)
PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT30);
PY_DICT_ADD_INT(GL_COLOR_ATTACHMENT31);
#endif
- PY_DICT_ADD_INT(GL_COMPARE_REF_TO_TEXTURE);
- PY_DICT_ADD_INT(GL_COMPRESSED_RED);
- PY_DICT_ADD_INT(GL_COMPRESSED_RED_RGTC1);
- PY_DICT_ADD_INT(GL_COMPRESSED_RG);
- PY_DICT_ADD_INT(GL_COMPRESSED_RG_RGTC2);
- PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RED_RGTC1);
- PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RG_RGTC2);
- PY_DICT_ADD_INT(GL_CONTEXT_FLAGS);
- PY_DICT_ADD_INT(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT);
- PY_DICT_ADD_INT(GL_DEPTH24_STENCIL8);
- PY_DICT_ADD_INT(GL_DEPTH32F_STENCIL8);
- PY_DICT_ADD_INT(GL_DEPTH_ATTACHMENT);
- PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32F);
- PY_DICT_ADD_INT(GL_DEPTH_STENCIL);
- PY_DICT_ADD_INT(GL_DEPTH_STENCIL_ATTACHMENT);
- PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER);
- PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER_BINDING);
- PY_DICT_ADD_INT(GL_FIXED_ONLY);
- PY_DICT_ADD_INT(GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_BINDING);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_COMPLETE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_DEFAULT);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_SRGB);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNDEFINED);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNSUPPORTED);
- PY_DICT_ADD_INT(GL_GREEN_INTEGER);
- PY_DICT_ADD_INT(GL_HALF_FLOAT);
- PY_DICT_ADD_INT(GL_INDEX);
- PY_DICT_ADD_INT(GL_INTERLEAVED_ATTRIBS);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_1D);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_1D_ARRAY);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_2D);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_ARRAY);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_3D);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_CUBE);
- PY_DICT_ADD_INT(GL_INVALID_FRAMEBUFFER_OPERATION);
- PY_DICT_ADD_INT(GL_MAJOR_VERSION);
- PY_DICT_ADD_INT(GL_MAP_FLUSH_EXPLICIT_BIT);
- PY_DICT_ADD_INT(GL_MAP_INVALIDATE_BUFFER_BIT);
- PY_DICT_ADD_INT(GL_MAP_INVALIDATE_RANGE_BIT);
- PY_DICT_ADD_INT(GL_MAP_READ_BIT);
- PY_DICT_ADD_INT(GL_MAP_UNSYNCHRONIZED_BIT);
- PY_DICT_ADD_INT(GL_MAP_WRITE_BIT);
- PY_DICT_ADD_INT(GL_MAX_ARRAY_TEXTURE_LAYERS);
- PY_DICT_ADD_INT(GL_MAX_CLIP_DISTANCES);
- PY_DICT_ADD_INT(GL_MAX_COLOR_ATTACHMENTS);
- PY_DICT_ADD_INT(GL_MAX_PROGRAM_TEXEL_OFFSET);
- PY_DICT_ADD_INT(GL_MAX_RENDERBUFFER_SIZE);
- PY_DICT_ADD_INT(GL_MAX_SAMPLES);
- PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
- PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_VARYING_COMPONENTS);
- PY_DICT_ADD_INT(GL_MINOR_VERSION);
- PY_DICT_ADD_INT(GL_MIN_PROGRAM_TEXEL_OFFSET);
- PY_DICT_ADD_INT(GL_NUM_EXTENSIONS);
- PY_DICT_ADD_INT(GL_PRIMITIVES_GENERATED);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D_ARRAY);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_ARRAY);
- PY_DICT_ADD_INT(GL_QUERY_BY_REGION_NO_WAIT);
- PY_DICT_ADD_INT(GL_QUERY_BY_REGION_WAIT);
- PY_DICT_ADD_INT(GL_QUERY_NO_WAIT);
- PY_DICT_ADD_INT(GL_QUERY_WAIT);
- PY_DICT_ADD_INT(GL_R11F_G11F_B10F);
- PY_DICT_ADD_INT(GL_R16);
- PY_DICT_ADD_INT(GL_R16F);
- PY_DICT_ADD_INT(GL_R16I);
- PY_DICT_ADD_INT(GL_R16UI);
- PY_DICT_ADD_INT(GL_R32F);
- PY_DICT_ADD_INT(GL_R32I);
- PY_DICT_ADD_INT(GL_R32UI);
- PY_DICT_ADD_INT(GL_R8);
- PY_DICT_ADD_INT(GL_R8I);
- PY_DICT_ADD_INT(GL_R8UI);
- PY_DICT_ADD_INT(GL_RASTERIZER_DISCARD);
- PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER);
- PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER_BINDING);
- PY_DICT_ADD_INT(GL_RED_INTEGER);
- PY_DICT_ADD_INT(GL_RENDERBUFFER);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_ALPHA_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_BINDING);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_BLUE_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_DEPTH_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_GREEN_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_HEIGHT);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_INTERNAL_FORMAT);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_RED_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_SAMPLES);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_STENCIL_SIZE);
- PY_DICT_ADD_INT(GL_RENDERBUFFER_WIDTH);
- PY_DICT_ADD_INT(GL_RG);
- PY_DICT_ADD_INT(GL_RG16);
- PY_DICT_ADD_INT(GL_RG16F);
- PY_DICT_ADD_INT(GL_RG16I);
- PY_DICT_ADD_INT(GL_RG16UI);
- PY_DICT_ADD_INT(GL_RG32F);
- PY_DICT_ADD_INT(GL_RG32I);
- PY_DICT_ADD_INT(GL_RG32UI);
- PY_DICT_ADD_INT(GL_RG8);
- PY_DICT_ADD_INT(GL_RG8I);
- PY_DICT_ADD_INT(GL_RG8UI);
- PY_DICT_ADD_INT(GL_RGB16F);
- PY_DICT_ADD_INT(GL_RGB16I);
- PY_DICT_ADD_INT(GL_RGB16UI);
- PY_DICT_ADD_INT(GL_RGB32F);
- PY_DICT_ADD_INT(GL_RGB32I);
- PY_DICT_ADD_INT(GL_RGB32UI);
- PY_DICT_ADD_INT(GL_RGB8I);
- PY_DICT_ADD_INT(GL_RGB8UI);
- PY_DICT_ADD_INT(GL_RGB9_E5);
- PY_DICT_ADD_INT(GL_RGBA16F);
- PY_DICT_ADD_INT(GL_RGBA16I);
- PY_DICT_ADD_INT(GL_RGBA16UI);
- PY_DICT_ADD_INT(GL_RGBA32F);
- PY_DICT_ADD_INT(GL_RGBA32I);
- PY_DICT_ADD_INT(GL_RGBA32UI);
- PY_DICT_ADD_INT(GL_RGBA8I);
- PY_DICT_ADD_INT(GL_RGBA8UI);
- PY_DICT_ADD_INT(GL_RGBA_INTEGER);
- PY_DICT_ADD_INT(GL_RGB_INTEGER);
- PY_DICT_ADD_INT(GL_RG_INTEGER);
- PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY);
- PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY_SHADOW);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY_SHADOW);
- PY_DICT_ADD_INT(GL_SAMPLER_CUBE_SHADOW);
- PY_DICT_ADD_INT(GL_SEPARATE_ATTRIBS);
- PY_DICT_ADD_INT(GL_STENCIL_ATTACHMENT);
- PY_DICT_ADD_INT(GL_STENCIL_INDEX1);
- PY_DICT_ADD_INT(GL_STENCIL_INDEX16);
- PY_DICT_ADD_INT(GL_STENCIL_INDEX4);
- PY_DICT_ADD_INT(GL_STENCIL_INDEX8);
- PY_DICT_ADD_INT(GL_TEXTURE_1D_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_2D_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_BLUE_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_GREEN_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_RED_TYPE);
- PY_DICT_ADD_INT(GL_TEXTURE_SHARED_SIZE);
- PY_DICT_ADD_INT(GL_TEXTURE_STENCIL_SIZE);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_MODE);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_START);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYINGS);
- PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_10F_11F_11F_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_24_8);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_5_9_9_9_REV);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_3D);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_CUBE);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC2);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC3);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC4);
- PY_DICT_ADD_INT(GL_UNSIGNED_NORMALIZED);
- PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BINDING);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_INTEGER);
- }
-
+ PY_DICT_ADD_INT(GL_COMPARE_REF_TO_TEXTURE);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RED);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RED_RGTC1);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RG);
+ PY_DICT_ADD_INT(GL_COMPRESSED_RG_RGTC2);
+ PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RED_RGTC1);
+ PY_DICT_ADD_INT(GL_COMPRESSED_SIGNED_RG_RGTC2);
+ PY_DICT_ADD_INT(GL_CONTEXT_FLAGS);
+ PY_DICT_ADD_INT(GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT);
+ PY_DICT_ADD_INT(GL_DEPTH24_STENCIL8);
+ PY_DICT_ADD_INT(GL_DEPTH32F_STENCIL8);
+ PY_DICT_ADD_INT(GL_DEPTH_ATTACHMENT);
+ PY_DICT_ADD_INT(GL_DEPTH_COMPONENT32F);
+ PY_DICT_ADD_INT(GL_DEPTH_STENCIL);
+ PY_DICT_ADD_INT(GL_DEPTH_STENCIL_ATTACHMENT);
+ PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER);
+ PY_DICT_ADD_INT(GL_DRAW_FRAMEBUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_FIXED_ONLY);
+ PY_DICT_ADD_INT(GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_COMPLETE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_DEFAULT);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_SRGB);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNDEFINED);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_UNSUPPORTED);
+ PY_DICT_ADD_INT(GL_GREEN_INTEGER);
+ PY_DICT_ADD_INT(GL_HALF_FLOAT);
+ PY_DICT_ADD_INT(GL_INDEX);
+ PY_DICT_ADD_INT(GL_INTERLEAVED_ATTRIBS);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_1D);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_2D);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_3D);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_CUBE);
+ PY_DICT_ADD_INT(GL_INVALID_FRAMEBUFFER_OPERATION);
+ PY_DICT_ADD_INT(GL_MAJOR_VERSION);
+ PY_DICT_ADD_INT(GL_MAP_FLUSH_EXPLICIT_BIT);
+ PY_DICT_ADD_INT(GL_MAP_INVALIDATE_BUFFER_BIT);
+ PY_DICT_ADD_INT(GL_MAP_INVALIDATE_RANGE_BIT);
+ PY_DICT_ADD_INT(GL_MAP_READ_BIT);
+ PY_DICT_ADD_INT(GL_MAP_UNSYNCHRONIZED_BIT);
+ PY_DICT_ADD_INT(GL_MAP_WRITE_BIT);
+ PY_DICT_ADD_INT(GL_MAX_ARRAY_TEXTURE_LAYERS);
+ PY_DICT_ADD_INT(GL_MAX_CLIP_DISTANCES);
+ PY_DICT_ADD_INT(GL_MAX_COLOR_ATTACHMENTS);
+ PY_DICT_ADD_INT(GL_MAX_PROGRAM_TEXEL_OFFSET);
+ PY_DICT_ADD_INT(GL_MAX_RENDERBUFFER_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_SAMPLES);
+ PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
+ PY_DICT_ADD_INT(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_VARYING_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MINOR_VERSION);
+ PY_DICT_ADD_INT(GL_MIN_PROGRAM_TEXEL_OFFSET);
+ PY_DICT_ADD_INT(GL_NUM_EXTENSIONS);
+ PY_DICT_ADD_INT(GL_PRIMITIVES_GENERATED);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_QUERY_BY_REGION_NO_WAIT);
+ PY_DICT_ADD_INT(GL_QUERY_BY_REGION_WAIT);
+ PY_DICT_ADD_INT(GL_QUERY_NO_WAIT);
+ PY_DICT_ADD_INT(GL_QUERY_WAIT);
+ PY_DICT_ADD_INT(GL_R11F_G11F_B10F);
+ PY_DICT_ADD_INT(GL_R16);
+ PY_DICT_ADD_INT(GL_R16F);
+ PY_DICT_ADD_INT(GL_R16I);
+ PY_DICT_ADD_INT(GL_R16UI);
+ PY_DICT_ADD_INT(GL_R32F);
+ PY_DICT_ADD_INT(GL_R32I);
+ PY_DICT_ADD_INT(GL_R32UI);
+ PY_DICT_ADD_INT(GL_R8);
+ PY_DICT_ADD_INT(GL_R8I);
+ PY_DICT_ADD_INT(GL_R8UI);
+ PY_DICT_ADD_INT(GL_RASTERIZER_DISCARD);
+ PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER);
+ PY_DICT_ADD_INT(GL_READ_FRAMEBUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_RED_INTEGER);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_ALPHA_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_BLUE_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_DEPTH_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_GREEN_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_HEIGHT);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_INTERNAL_FORMAT);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_RED_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_SAMPLES);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_STENCIL_SIZE);
+ PY_DICT_ADD_INT(GL_RENDERBUFFER_WIDTH);
+ PY_DICT_ADD_INT(GL_RG);
+ PY_DICT_ADD_INT(GL_RG16);
+ PY_DICT_ADD_INT(GL_RG16F);
+ PY_DICT_ADD_INT(GL_RG16I);
+ PY_DICT_ADD_INT(GL_RG16UI);
+ PY_DICT_ADD_INT(GL_RG32F);
+ PY_DICT_ADD_INT(GL_RG32I);
+ PY_DICT_ADD_INT(GL_RG32UI);
+ PY_DICT_ADD_INT(GL_RG8);
+ PY_DICT_ADD_INT(GL_RG8I);
+ PY_DICT_ADD_INT(GL_RG8UI);
+ PY_DICT_ADD_INT(GL_RGB16F);
+ PY_DICT_ADD_INT(GL_RGB16I);
+ PY_DICT_ADD_INT(GL_RGB16UI);
+ PY_DICT_ADD_INT(GL_RGB32F);
+ PY_DICT_ADD_INT(GL_RGB32I);
+ PY_DICT_ADD_INT(GL_RGB32UI);
+ PY_DICT_ADD_INT(GL_RGB8I);
+ PY_DICT_ADD_INT(GL_RGB8UI);
+ PY_DICT_ADD_INT(GL_RGB9_E5);
+ PY_DICT_ADD_INT(GL_RGBA16F);
+ PY_DICT_ADD_INT(GL_RGBA16I);
+ PY_DICT_ADD_INT(GL_RGBA16UI);
+ PY_DICT_ADD_INT(GL_RGBA32F);
+ PY_DICT_ADD_INT(GL_RGBA32I);
+ PY_DICT_ADD_INT(GL_RGBA32UI);
+ PY_DICT_ADD_INT(GL_RGBA8I);
+ PY_DICT_ADD_INT(GL_RGBA8UI);
+ PY_DICT_ADD_INT(GL_RGBA_INTEGER);
+ PY_DICT_ADD_INT(GL_RGB_INTEGER);
+ PY_DICT_ADD_INT(GL_RG_INTEGER);
+ PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_SAMPLER_1D_ARRAY_SHADOW);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_ARRAY_SHADOW);
+ PY_DICT_ADD_INT(GL_SAMPLER_CUBE_SHADOW);
+ PY_DICT_ADD_INT(GL_SEPARATE_ATTRIBS);
+ PY_DICT_ADD_INT(GL_STENCIL_ATTACHMENT);
+ PY_DICT_ADD_INT(GL_STENCIL_INDEX1);
+ PY_DICT_ADD_INT(GL_STENCIL_INDEX16);
+ PY_DICT_ADD_INT(GL_STENCIL_INDEX4);
+ PY_DICT_ADD_INT(GL_STENCIL_INDEX8);
+ PY_DICT_ADD_INT(GL_TEXTURE_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_ALPHA_TYPE);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_BLUE_TYPE);
+ PY_DICT_ADD_INT(GL_TEXTURE_DEPTH_TYPE);
+ PY_DICT_ADD_INT(GL_TEXTURE_GREEN_TYPE);
+ PY_DICT_ADD_INT(GL_TEXTURE_RED_TYPE);
+ PY_DICT_ADD_INT(GL_TEXTURE_SHARED_SIZE);
+ PY_DICT_ADD_INT(GL_TEXTURE_STENCIL_SIZE);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_MODE);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_SIZE);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_BUFFER_START);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYINGS);
+ PY_DICT_ADD_INT(GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_10F_11F_11F_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_24_8);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_5_9_9_9_REV);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_3D);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_CUBE);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC2);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC3);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_VEC4);
+ PY_DICT_ADD_INT(GL_UNSIGNED_NORMALIZED);
+ PY_DICT_ADD_INT(GL_VERTEX_ARRAY_BINDING);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_INTEGER);
+}
+static void init_bgl_version_3_1_constants(PyObject *dict)
+{
/* GL_VERSION_3_1 */
- {
- PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCKS);
- PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH);
- PY_DICT_ADD_INT(GL_COPY_READ_BUFFER);
- PY_DICT_ADD_INT(GL_COPY_WRITE_BUFFER);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_RECT);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_BUFFER);
- PY_DICT_ADD_INT(GL_INVALID_INDEX);
- PY_DICT_ADD_INT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_COMBINED_UNIFORM_BLOCKS);
- PY_DICT_ADD_INT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS);
- PY_DICT_ADD_INT(GL_MAX_RECTANGLE_TEXTURE_SIZE);
- PY_DICT_ADD_INT(GL_MAX_TEXTURE_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_MAX_UNIFORM_BLOCK_SIZE);
- PY_DICT_ADD_INT(GL_MAX_UNIFORM_BUFFER_BINDINGS);
- PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_BLOCKS);
- PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART);
- PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART_INDEX);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_RECTANGLE);
- PY_DICT_ADD_INT(GL_R16_SNORM);
- PY_DICT_ADD_INT(GL_R8_SNORM);
- PY_DICT_ADD_INT(GL_RG16_SNORM);
- PY_DICT_ADD_INT(GL_RG8_SNORM);
- PY_DICT_ADD_INT(GL_RGB16_SNORM);
- PY_DICT_ADD_INT(GL_RGB8_SNORM);
- PY_DICT_ADD_INT(GL_RGBA16_SNORM);
- PY_DICT_ADD_INT(GL_RGBA8_SNORM);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT_SHADOW);
- PY_DICT_ADD_INT(GL_SAMPLER_BUFFER);
- PY_DICT_ADD_INT(GL_SIGNED_NORMALIZED);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_BUFFER);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_RECTANGLE);
- PY_DICT_ADD_INT(GL_TEXTURE_BUFFER);
- PY_DICT_ADD_INT(GL_TEXTURE_BUFFER_DATA_STORE_BINDING);
- PY_DICT_ADD_INT(GL_TEXTURE_RECTANGLE);
- PY_DICT_ADD_INT(GL_UNIFORM_ARRAY_STRIDE);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_BINDING);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_DATA_SIZE);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_INDEX);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_NAME_LENGTH);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER);
- PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER);
- PY_DICT_ADD_INT(GL_UNIFORM_BUFFER);
- PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_BINDING);
- PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
- PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_SIZE);
- PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_START);
- PY_DICT_ADD_INT(GL_UNIFORM_IS_ROW_MAJOR);
- PY_DICT_ADD_INT(GL_UNIFORM_MATRIX_STRIDE);
- PY_DICT_ADD_INT(GL_UNIFORM_NAME_LENGTH);
- PY_DICT_ADD_INT(GL_UNIFORM_OFFSET);
- PY_DICT_ADD_INT(GL_UNIFORM_SIZE);
- PY_DICT_ADD_INT(GL_UNIFORM_TYPE);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_RECT);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_BUFFER);
- }
+ PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCKS);
+ PY_DICT_ADD_INT(GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH);
+ PY_DICT_ADD_INT(GL_COPY_READ_BUFFER);
+ PY_DICT_ADD_INT(GL_COPY_WRITE_BUFFER);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_RECT);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_BUFFER);
+ PY_DICT_ADD_INT(GL_INVALID_INDEX);
+ PY_DICT_ADD_INT(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_COMBINED_UNIFORM_BLOCKS);
+ PY_DICT_ADD_INT(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_BLOCKS);
+ PY_DICT_ADD_INT(GL_MAX_RECTANGLE_TEXTURE_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_TEXTURE_BUFFER_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_UNIFORM_BLOCK_SIZE);
+ PY_DICT_ADD_INT(GL_MAX_UNIFORM_BUFFER_BINDINGS);
+ PY_DICT_ADD_INT(GL_MAX_VERTEX_UNIFORM_BLOCKS);
+ PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART);
+ PY_DICT_ADD_INT(GL_PRIMITIVE_RESTART_INDEX);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_RECTANGLE);
+ PY_DICT_ADD_INT(GL_R16_SNORM);
+ PY_DICT_ADD_INT(GL_R8_SNORM);
+ PY_DICT_ADD_INT(GL_RG16_SNORM);
+ PY_DICT_ADD_INT(GL_RG8_SNORM);
+ PY_DICT_ADD_INT(GL_RGB16_SNORM);
+ PY_DICT_ADD_INT(GL_RGB8_SNORM);
+ PY_DICT_ADD_INT(GL_RGBA16_SNORM);
+ PY_DICT_ADD_INT(GL_RGBA8_SNORM);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_RECT_SHADOW);
+ PY_DICT_ADD_INT(GL_SAMPLER_BUFFER);
+ PY_DICT_ADD_INT(GL_SIGNED_NORMALIZED);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_BUFFER);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_RECTANGLE);
+ PY_DICT_ADD_INT(GL_TEXTURE_BUFFER);
+ PY_DICT_ADD_INT(GL_TEXTURE_BUFFER_DATA_STORE_BINDING);
+ PY_DICT_ADD_INT(GL_TEXTURE_RECTANGLE);
+ PY_DICT_ADD_INT(GL_UNIFORM_ARRAY_STRIDE);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_BINDING);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_DATA_SIZE);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_INDEX);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_NAME_LENGTH);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER);
+ PY_DICT_ADD_INT(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER);
+ PY_DICT_ADD_INT(GL_UNIFORM_BUFFER);
+ PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_BINDING);
+ PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_SIZE);
+ PY_DICT_ADD_INT(GL_UNIFORM_BUFFER_START);
+ PY_DICT_ADD_INT(GL_UNIFORM_IS_ROW_MAJOR);
+ PY_DICT_ADD_INT(GL_UNIFORM_MATRIX_STRIDE);
+ PY_DICT_ADD_INT(GL_UNIFORM_NAME_LENGTH);
+ PY_DICT_ADD_INT(GL_UNIFORM_OFFSET);
+ PY_DICT_ADD_INT(GL_UNIFORM_SIZE);
+ PY_DICT_ADD_INT(GL_UNIFORM_TYPE);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_RECT);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_BUFFER);
+}
+static void init_bgl_version_3_2_constants(PyObject *dict)
+/* GL_VERSION_3_2 */
+{
+ PY_DICT_ADD_INT(GL_ALREADY_SIGNALED);
+ PY_DICT_ADD_INT(GL_CONDITION_SATISFIED);
+ PY_DICT_ADD_INT(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT);
+ PY_DICT_ADD_INT(GL_CONTEXT_CORE_PROFILE_BIT);
+ PY_DICT_ADD_INT(GL_CONTEXT_PROFILE_MASK);
+ PY_DICT_ADD_INT(GL_DEPTH_CLAMP);
+ PY_DICT_ADD_INT(GL_FIRST_VERTEX_CONVENTION);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_LAYERED);
+ PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
+ PY_DICT_ADD_INT(GL_GEOMETRY_INPUT_TYPE);
+ PY_DICT_ADD_INT(GL_GEOMETRY_OUTPUT_TYPE);
+ PY_DICT_ADD_INT(GL_GEOMETRY_SHADER);
+ PY_DICT_ADD_INT(GL_GEOMETRY_VERTICES_OUT);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_LAST_VERTEX_CONVENTION);
+ PY_DICT_ADD_INT(GL_LINES_ADJACENCY);
+ PY_DICT_ADD_INT(GL_LINE_STRIP_ADJACENCY);
+ PY_DICT_ADD_INT(GL_MAX_COLOR_TEXTURE_SAMPLES);
+ PY_DICT_ADD_INT(GL_MAX_DEPTH_TEXTURE_SAMPLES);
+ PY_DICT_ADD_INT(GL_MAX_FRAGMENT_INPUT_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_INPUT_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_VERTICES);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS);
+ PY_DICT_ADD_INT(GL_MAX_INTEGER_SAMPLES);
+ PY_DICT_ADD_INT(GL_MAX_SAMPLE_MASK_WORDS);
+ PY_DICT_ADD_INT(GL_MAX_SERVER_WAIT_TIMEOUT);
+ PY_DICT_ADD_INT(GL_MAX_VERTEX_OUTPUT_COMPONENTS);
+ PY_DICT_ADD_INT(GL_OBJECT_TYPE);
+ PY_DICT_ADD_INT(GL_PROGRAM_POINT_SIZE);
+ PY_DICT_ADD_INT(GL_PROVOKING_VERTEX);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_SAMPLE_MASK);
+ PY_DICT_ADD_INT(GL_SAMPLE_MASK_VALUE);
+ PY_DICT_ADD_INT(GL_SAMPLE_POSITION);
+ PY_DICT_ADD_INT(GL_SIGNALED);
+ PY_DICT_ADD_INT(GL_SYNC_CONDITION);
+ PY_DICT_ADD_INT(GL_SYNC_FENCE);
+ PY_DICT_ADD_INT(GL_SYNC_FLAGS);
+ PY_DICT_ADD_INT(GL_SYNC_FLUSH_COMMANDS_BIT);
+ PY_DICT_ADD_INT(GL_SYNC_GPU_COMMANDS_COMPLETE);
+ PY_DICT_ADD_INT(GL_SYNC_STATUS);
+ PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ PY_DICT_ADD_INT(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS);
+ PY_DICT_ADD_INT(GL_TEXTURE_SAMPLES);
+ PY_DICT_ADD_INT(GL_TIMEOUT_EXPIRED);
+ PY_DICT_ADD_INT64(GL_TIMEOUT_IGNORED);
+ PY_DICT_ADD_INT(GL_TRIANGLES_ADJACENCY);
+ PY_DICT_ADD_INT(GL_TRIANGLE_STRIP_ADJACENCY);
+ PY_DICT_ADD_INT(GL_UNSIGNALED);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE);
+ PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY);
+ PY_DICT_ADD_INT(GL_WAIT_FAILED);
+}
+static void init_bgl_version_3_3_constants(PyObject *dict)
+{
+ /* GL_VERSION_3_3 */
+ PY_DICT_ADD_INT(GL_ANY_SAMPLES_PASSED);
+ PY_DICT_ADD_INT(GL_INT_2_10_10_10_REV);
+ PY_DICT_ADD_INT(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_ALPHA);
+ PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_COLOR);
+ PY_DICT_ADD_INT(GL_RGB10_A2UI);
+ PY_DICT_ADD_INT(GL_SAMPLER_BINDING);
+ PY_DICT_ADD_INT(GL_SRC1_COLOR);
+ PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_A);
+ PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_B);
+ PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_G);
+ PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_R);
+ PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_RGBA);
+ PY_DICT_ADD_INT(GL_TIMESTAMP);
+ PY_DICT_ADD_INT(GL_TIME_ELAPSED);
+ PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR);
+}
- /* GL_VERSION_3_2 */
- {
- PY_DICT_ADD_INT(GL_ALREADY_SIGNALED);
- PY_DICT_ADD_INT(GL_CONDITION_SATISFIED);
- PY_DICT_ADD_INT(GL_CONTEXT_COMPATIBILITY_PROFILE_BIT);
- PY_DICT_ADD_INT(GL_CONTEXT_CORE_PROFILE_BIT);
- PY_DICT_ADD_INT(GL_CONTEXT_PROFILE_MASK);
- PY_DICT_ADD_INT(GL_DEPTH_CLAMP);
- PY_DICT_ADD_INT(GL_FIRST_VERTEX_CONVENTION);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_ATTACHMENT_LAYERED);
- PY_DICT_ADD_INT(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
- PY_DICT_ADD_INT(GL_GEOMETRY_INPUT_TYPE);
- PY_DICT_ADD_INT(GL_GEOMETRY_OUTPUT_TYPE);
- PY_DICT_ADD_INT(GL_GEOMETRY_SHADER);
- PY_DICT_ADD_INT(GL_GEOMETRY_VERTICES_OUT);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_LAST_VERTEX_CONVENTION);
- PY_DICT_ADD_INT(GL_LINES_ADJACENCY);
- PY_DICT_ADD_INT(GL_LINE_STRIP_ADJACENCY);
- PY_DICT_ADD_INT(GL_MAX_COLOR_TEXTURE_SAMPLES);
- PY_DICT_ADD_INT(GL_MAX_DEPTH_TEXTURE_SAMPLES);
- PY_DICT_ADD_INT(GL_MAX_FRAGMENT_INPUT_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_INPUT_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_OUTPUT_VERTICES);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_GEOMETRY_UNIFORM_COMPONENTS);
- PY_DICT_ADD_INT(GL_MAX_INTEGER_SAMPLES);
- PY_DICT_ADD_INT(GL_MAX_SAMPLE_MASK_WORDS);
- PY_DICT_ADD_INT(GL_MAX_SERVER_WAIT_TIMEOUT);
- PY_DICT_ADD_INT(GL_MAX_VERTEX_OUTPUT_COMPONENTS);
- PY_DICT_ADD_INT(GL_OBJECT_TYPE);
- PY_DICT_ADD_INT(GL_PROGRAM_POINT_SIZE);
- PY_DICT_ADD_INT(GL_PROVOKING_VERTEX);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_SAMPLER_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_SAMPLE_MASK);
- PY_DICT_ADD_INT(GL_SAMPLE_MASK_VALUE);
- PY_DICT_ADD_INT(GL_SAMPLE_POSITION);
- PY_DICT_ADD_INT(GL_SIGNALED);
- PY_DICT_ADD_INT(GL_SYNC_CONDITION);
- PY_DICT_ADD_INT(GL_SYNC_FENCE);
- PY_DICT_ADD_INT(GL_SYNC_FLAGS);
- PY_DICT_ADD_INT(GL_SYNC_FLUSH_COMMANDS_BIT);
- PY_DICT_ADD_INT(GL_SYNC_GPU_COMMANDS_COMPLETE);
- PY_DICT_ADD_INT(GL_SYNC_STATUS);
- PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_TEXTURE_CUBE_MAP_SEAMLESS);
- PY_DICT_ADD_INT(GL_TEXTURE_FIXED_SAMPLE_LOCATIONS);
- PY_DICT_ADD_INT(GL_TEXTURE_SAMPLES);
- PY_DICT_ADD_INT(GL_TIMEOUT_EXPIRED);
- PY_DICT_ADD_INT64(GL_TIMEOUT_IGNORED);
- PY_DICT_ADD_INT(GL_TRIANGLES_ADJACENCY);
- PY_DICT_ADD_INT(GL_TRIANGLE_STRIP_ADJACENCY);
- PY_DICT_ADD_INT(GL_UNSIGNALED);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE);
- PY_DICT_ADD_INT(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY);
- PY_DICT_ADD_INT(GL_WAIT_FAILED);
- }
+PyObject *BPyInit_bgl(void)
+{
+ PyObject *submodule, *dict;
+ submodule = PyModule_Create(&BGL_module_def);
+ dict = PyModule_GetDict(submodule);
- /* GL_VERSION_3_3 */
- {
- PY_DICT_ADD_INT(GL_ANY_SAMPLES_PASSED);
- PY_DICT_ADD_INT(GL_INT_2_10_10_10_REV);
- PY_DICT_ADD_INT(GL_MAX_DUAL_SOURCE_DRAW_BUFFERS);
- PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_ALPHA);
- PY_DICT_ADD_INT(GL_ONE_MINUS_SRC1_COLOR);
- PY_DICT_ADD_INT(GL_RGB10_A2UI);
- PY_DICT_ADD_INT(GL_SAMPLER_BINDING);
- PY_DICT_ADD_INT(GL_SRC1_COLOR);
- PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_A);
- PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_B);
- PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_G);
- PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_R);
- PY_DICT_ADD_INT(GL_TEXTURE_SWIZZLE_RGBA);
- PY_DICT_ADD_INT(GL_TIMESTAMP);
- PY_DICT_ADD_INT(GL_TIME_ELAPSED);
- PY_DICT_ADD_INT(GL_VERTEX_ATTRIB_ARRAY_DIVISOR);
+ if (PyType_Ready(&BGL_bufferType) < 0) {
+ return NULL; /* should never happen */
}
+ PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType);
+ Py_INCREF((PyObject *)&BGL_bufferType);
+
+ init_bgl_version_1_0_methods(submodule, dict);
+ init_bgl_version_1_1_methods(submodule, dict);
+ init_bgl_version_1_2_methods(submodule, dict);
+ init_bgl_version_1_3_methods(submodule, dict);
+ init_bgl_version_1_4_methods(submodule, dict);
+ init_bgl_version_1_5_methods(submodule, dict);
+ init_bgl_version_2_0_methods(submodule, dict);
+ init_bgl_version_2_1_methods(submodule, dict);
+ init_bgl_version_3_0_methods(submodule, dict);
+ init_bgl_version_3_1_methods(submodule, dict);
+ init_bgl_version_3_2_methods(submodule, dict);
+ init_bgl_version_3_3_methods(submodule, dict);
+
+ init_bgl_version_1_1_constants(dict);
+ init_bgl_version_1_2_constants(dict);
+ init_bgl_version_1_3_constants(dict);
+ init_bgl_version_1_4_constants(dict);
+ init_bgl_version_1_5_constants(dict);
+ init_bgl_version_2_0_constants(dict);
+ init_bgl_version_2_1_constants(dict);
+ init_bgl_version_3_0_constants(dict);
+ init_bgl_version_3_1_constants(dict);
+ init_bgl_version_3_2_constants(dict);
+ init_bgl_version_3_3_constants(dict);
+
return submodule;
}
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index cabeeba18b9..615ce514a3e 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -51,13 +51,12 @@ static PyObject *idprop_py_from_idp_string(const IDProperty *prop)
if (prop->subtype == IDP_STRING_SUB_BYTE) {
return PyBytes_FromStringAndSize(IDP_String(prop), prop->len);
}
- else {
+
#ifdef USE_STRING_COERCE
- return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
+ return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
#else
- return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1);
+ return PyUnicode_FromStringAndSize(IDP_String(prop), prop->len - 1);
#endif
- }
}
static PyObject *idprop_py_from_idp_int(const IDProperty *prop)
@@ -479,10 +478,10 @@ static IDProperty *idp_from_PySequence_Buffer(const char *name, Py_buffer *buffe
/* should never happen as the type has been checked before */
return NULL;
}
- else {
- val.array.type = id_type;
- val.array.len = buffer->len / buffer->itemsize;
- }
+
+ val.array.type = id_type;
+ val.array.len = buffer->len / buffer->itemsize;
+
prop = IDP_New(IDP_ARRAY, &val, name);
memcpy(IDP_Array(prop), buffer->buf, buffer->len);
return prop;
@@ -576,17 +575,15 @@ static IDProperty *idp_from_PySequence(const char *name, PyObject *ob)
PyBuffer_Release(&buffer);
return prop;
}
- else {
- PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop");
- if (ob_seq_fast != NULL) {
- IDProperty *prop = idp_from_PySequence_Fast(name, ob_seq_fast);
- Py_DECREF(ob_seq_fast);
- return prop;
- }
- else {
- return NULL;
- }
+
+ PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop");
+ if (ob_seq_fast != NULL) {
+ IDProperty *prop = idp_from_PySequence_Fast(name, ob_seq_fast);
+ Py_DECREF(ob_seq_fast);
+ return prop;
}
+
+ return NULL;
}
static IDProperty *idp_from_PyMapping(const char *name, PyObject *ob)
@@ -641,29 +638,28 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob)
if (PyFloat_Check(ob)) {
return idp_from_PyFloat(name, ob);
}
- else if (PyLong_Check(ob)) {
+ if (PyLong_Check(ob)) {
return idp_from_PyLong(name, ob);
}
- else if (PyUnicode_Check(ob)) {
+ if (PyUnicode_Check(ob)) {
return idp_from_PyUnicode(name, ob);
}
- else if (PyBytes_Check(ob)) {
+ if (PyBytes_Check(ob)) {
return idp_from_PyBytes(name, ob);
}
- else if (PySequence_Check(ob)) {
+ if (PySequence_Check(ob)) {
return idp_from_PySequence(name, ob);
}
- else if (ob == Py_None || pyrna_id_CheckPyObject(ob)) {
+ if (ob == Py_None || pyrna_id_CheckPyObject(ob)) {
return idp_from_DatablockPointer(name, ob);
}
- else if (PyMapping_Check(ob)) {
+ if (PyMapping_Check(ob)) {
return idp_from_PyMapping(name, ob);
}
- else {
- PyErr_Format(
- PyExc_TypeError, "invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name);
- return NULL;
- }
+
+ PyErr_Format(
+ PyExc_TypeError, "invalid id-property type %.200s not supported", Py_TYPE(ob)->tp_name);
+ return NULL;
}
/** \} */
@@ -736,21 +732,19 @@ int BPy_Wrap_SetMapItem(IDProperty *prop, PyObject *key, PyObject *val)
IDP_FreeFromGroup(prop, pkey);
return 0;
}
- else {
- PyErr_SetString(PyExc_KeyError, "property not found in group");
- return -1;
- }
+
+ PyErr_SetString(PyExc_KeyError, "property not found in group");
+ return -1;
}
- else {
- bool ok;
- ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val);
- if (ok == false) {
- return -1;
- }
+ bool ok;
- return 0;
+ ok = BPy_IDProperty_Map_ValidateAndCreate(key, prop, val);
+ if (ok == false) {
+ return -1;
}
+
+ return 0;
}
static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject *val)
@@ -1485,7 +1479,7 @@ static PyObject *BPy_IDArray_subscript(BPy_IDArray *self, PyObject *item)
}
return BPy_IDArray_GetItem(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->prop->len, &start, &stop, &step, &slicelength) < 0) {
@@ -1495,21 +1489,19 @@ static PyObject *BPy_IDArray_subscript(BPy_IDArray *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return BPy_IDArray_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "vector indices must be integers, not %.200s",
- __func__,
- Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
return NULL;
}
+
+ PyErr_Format(PyExc_TypeError,
+ "vector indices must be integers, not %.200s",
+ __func__,
+ Py_TYPE(item)->tp_name);
+ return NULL;
}
static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject *value)
@@ -1524,7 +1516,7 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject
}
return BPy_IDArray_SetItem(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->prop->len, &start, &stop, &step, &slicelength) < 0) {
@@ -1534,16 +1526,14 @@ static int BPy_IDArray_ass_subscript(BPy_IDArray *self, PyObject *item, PyObject
if (step == 1) {
return BPy_IDArray_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_TypeError, "slice steps not supported with vectors");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
static PyMappingMethods BPy_IDArray_AsMapping = {
@@ -1709,14 +1699,12 @@ static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
BPy_IDGroup_WrapData(self->group->id, cur, self->group->prop));
return ret;
}
- else {
- return PyUnicode_FromString(cur->name);
- }
- }
- else {
- PyErr_SetNone(PyExc_StopIteration);
- return NULL;
+
+ return PyUnicode_FromString(cur->name);
}
+
+ PyErr_SetNone(PyExc_StopIteration);
+ return NULL;
}
PyTypeObject BPy_IDGroup_Iter_Type = {
diff --git a/source/blender/python/generic/imbuf_py_api.c b/source/blender/python/generic/imbuf_py_api.c
index 8a02638786d..3536236754e 100644
--- a/source/blender/python/generic/imbuf_py_api.c
+++ b/source/blender/python/generic/imbuf_py_api.c
@@ -57,11 +57,10 @@ static int py_imbuf_valid_check(Py_ImBuf *self)
if (LIKELY(self->ibuf)) {
return 0;
}
- else {
- PyErr_Format(
- PyExc_ReferenceError, "ImBuf data of type %.200s has been freed", Py_TYPE(self)->tp_name);
- return -1;
- }
+
+ PyErr_Format(
+ PyExc_ReferenceError, "ImBuf data of type %.200s has been freed", Py_TYPE(self)->tp_name);
+ return -1;
}
#define PY_IMBUF_CHECK_OBJ(obj) \
@@ -324,9 +323,8 @@ static PyObject *py_imbuf_repr(Py_ImBuf *self)
return PyUnicode_FromFormat(
"<imbuf: address=%p, filepath='%s', size=(%d, %d)>", ibuf, ibuf->name, ibuf->x, ibuf->y);
}
- else {
- return PyUnicode_FromString("<imbuf: address=0x0>");
- }
+
+ return PyUnicode_FromString("<imbuf: address=0x0>");
}
static Py_hash_t py_imbuf_hash(Py_ImBuf *self)
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 37ed96bcaa0..caae5c4e122 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -51,6 +51,10 @@
# include "BLI_math_base.h" /* isfinite() */
#endif
+/* -------------------------------------------------------------------- */
+/** \name Fast Python to C Array Conversion for Primitive Types
+ * \{ */
+
/* array utility function */
int PyC_AsArray_FAST(void *array,
PyObject *value_fast,
@@ -137,11 +141,12 @@ int PyC_AsArray(void *array,
return ret;
}
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Typed Tuple Packing
*
* \note See #PyC_Tuple_Pack_* macros that take multiple arguments.
- *
* \{ */
/* array utility function */
@@ -192,6 +197,10 @@ PyObject *PyC_Tuple_PackArray_Bool(const bool *array, uint len)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name Tuple/List Filling
+ * \{ */
+
/**
* Caller needs to ensure tuple is uninitialized.
* Handy for filling a tuple with None for eg.
@@ -218,6 +227,12 @@ void PyC_List_Fill(PyObject *list, PyObject *value)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Bool/Enum Argument Parsing
+ * \{ */
+
/**
* Use with PyArg_ParseTuple's "O&" formatting.
*
@@ -274,8 +289,16 @@ int PyC_CheckArgs_DeepCopy(PyObject *args)
return PyArg_ParseTuple(args, "|O!:__deepcopy__", &PyDict_Type, &dummy_pydict) != 0;
}
+/** \} */
+
#ifndef MATH_STANDALONE
+/* -------------------------------------------------------------------- */
+/** \name Simple Printing (for debugging)
+ *
+ * These are useful to run directly from a debugger to be able to inspect the state.
+ * \{ */
+
/* for debugging */
void PyC_ObSpit(const char *name, PyObject *var)
{
@@ -352,12 +375,11 @@ void PyC_StackSpit(void)
fprintf(stderr, "python line lookup failed, interpreter inactive\n");
return;
}
- else {
- /* lame but handy */
- PyGILState_STATE gilstate = PyGILState_Ensure();
- PyRun_SimpleString("__import__('traceback').print_stack()");
- PyGILState_Release(gilstate);
- }
+
+ /* lame but handy */
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+ PyRun_SimpleString("__import__('traceback').print_stack()");
+ PyGILState_Release(gilstate);
}
void PyC_StackPrint(/* FILE */ void *fp)
@@ -374,6 +396,12 @@ void PyC_StackPrint(/* FILE */ void *fp)
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Access Current Frame File Name & Line Number
+ * \{ */
+
void PyC_FileAndNum(const char **r_filename, int *r_lineno)
{
PyFrameObject *frame;
@@ -433,6 +461,12 @@ void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno)
PyC_FileAndNum(r_filename, r_lineno);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Object Access Utilities
+ * \{ */
+
/* Would be nice if python had this built in */
PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
{
@@ -461,6 +495,12 @@ PyObject *PyC_Object_GetAttrStringArgs(PyObject *o, Py_ssize_t n, ...)
return item;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Frozen Set Creation
+ * \{ */
+
PyObject *PyC_FrozenSetFromStrings(const char **strings)
{
const char **str;
@@ -477,6 +517,12 @@ PyObject *PyC_FrozenSetFromStrings(const char **strings)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Utilities
+ * \{ */
+
/**
* Similar to #PyErr_Format(),
*
@@ -542,6 +588,12 @@ void PyC_Err_PrintWithFunc(PyObject *py_func)
_PyUnicode_AsString(((PyFunctionObject *)py_func)->func_name));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Exception Buffer Access
+ * \{ */
+
/* returns the exception string as a new PyUnicode object, depends on external traceback module */
# if 0
@@ -648,7 +700,7 @@ error_cleanup:
PyObject *PyC_ExceptionBuffer_Simple(void)
{
- PyObject *string_io_buf;
+ PyObject *string_io_buf = NULL;
PyObject *error_type, *error_value, *error_traceback;
@@ -662,7 +714,19 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
return NULL;
}
- string_io_buf = PyObject_Str(error_value);
+ if (PyErr_GivenExceptionMatches(error_type, PyExc_SyntaxError)) {
+ /* Special exception for syntax errors,
+ * in these cases the full error is verbose and not very useful,
+ * just use the initial text so we know what the error is. */
+ if (PyTuple_CheckExact(error_value) && PyTuple_GET_SIZE(error_value) >= 1) {
+ string_io_buf = PyObject_Str(PyTuple_GET_ITEM(error_value, 0));
+ }
+ }
+
+ if (string_io_buf == NULL) {
+ string_io_buf = PyObject_Str(error_value);
+ }
+
/* Python does this too */
if (UNLIKELY(string_io_buf == NULL)) {
string_io_buf = PyUnicode_FromFormat("<unprintable %s object>", Py_TYPE(error_value)->tp_name);
@@ -675,6 +739,14 @@ PyObject *PyC_ExceptionBuffer_Simple(void)
return string_io_buf;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Unicode Conversion
+ *
+ * In some cases we need to coerce strings, avoid doing this inline.
+ * \{ */
+
/* string conversion, escape non-unicode chars, coerce must be set to NULL */
const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObject **coerce)
{
@@ -687,22 +759,20 @@ const char *PyC_UnicodeAsByteAndSize(PyObject *py_str, Py_ssize_t *size, PyObjec
* chars since blender doesn't limit this */
return result;
}
- else {
- PyErr_Clear();
- if (PyBytes_Check(py_str)) {
- *size = PyBytes_GET_SIZE(py_str);
- return PyBytes_AS_STRING(py_str);
- }
- else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- *size = PyBytes_GET_SIZE(*coerce);
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* leave error raised from EncodeFS */
- return NULL;
- }
+ PyErr_Clear();
+
+ if (PyBytes_Check(py_str)) {
+ *size = PyBytes_GET_SIZE(py_str);
+ return PyBytes_AS_STRING(py_str);
}
+ if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ *size = PyBytes_GET_SIZE(*coerce);
+ return PyBytes_AS_STRING(*coerce);
+ }
+
+ /* leave error raised from EncodeFS */
+ return NULL;
}
const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
@@ -716,20 +786,18 @@ const char *PyC_UnicodeAsByte(PyObject *py_str, PyObject **coerce)
* chars since blender doesn't limit this. */
return result;
}
- else {
- PyErr_Clear();
- if (PyBytes_Check(py_str)) {
- return PyBytes_AS_STRING(py_str);
- }
- else if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
- return PyBytes_AS_STRING(*coerce);
- }
- else {
- /* leave error raised from EncodeFS */
- return NULL;
- }
+ PyErr_Clear();
+
+ if (PyBytes_Check(py_str)) {
+ return PyBytes_AS_STRING(py_str);
}
+ if ((*coerce = PyUnicode_EncodeFSDefault(py_str))) {
+ return PyBytes_AS_STRING(*coerce);
+ }
+
+ /* leave error raised from EncodeFS */
+ return NULL;
}
PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
@@ -740,12 +808,11 @@ PyObject *PyC_UnicodeFromByteAndSize(const char *str, Py_ssize_t size)
* chars since blender doesn't limit this */
return result;
}
- else {
- PyErr_Clear();
- /* this means paths will always be accessible once converted, on all OS's */
- result = PyUnicode_DecodeFSDefaultAndSize(str, size);
- return result;
- }
+
+ PyErr_Clear();
+ /* this means paths will always be accessible once converted, on all OS's */
+ result = PyUnicode_DecodeFSDefaultAndSize(str, size);
+ return result;
}
PyObject *PyC_UnicodeFromByte(const char *str)
@@ -753,6 +820,12 @@ PyObject *PyC_UnicodeFromByte(const char *str)
return PyC_UnicodeFromByteAndSize(str, strlen(str));
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Name Space Creation/Manipulation
+ * \{ */
+
/*****************************************************************************
* Description: This function creates a new Python dictionary object.
* note: dict is owned by sys.modules["__main__"] module, reference is borrowed
@@ -818,8 +891,18 @@ void PyC_MainModule_Restore(PyObject *main_mod)
Py_XDECREF(main_mod);
}
-/* Must be called before Py_Initialize,
- * expects output of BKE_appdir_folder_id(BLENDER_PYTHON, NULL). */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
+/**
+ * - Must be called before #Py_Initialize.
+ * - Expects output of `BKE_appdir_folder_id(BLENDER_PYTHON, NULL)`.
+ * - Note that the `PYTHONPATH` environment variable isn't reliable, see T31506.
+ Use #Py_SetPythonHome instead.
+ */
void PyC_SetHomePath(const char *py_path_bundle)
{
if (py_path_bundle == NULL) {
@@ -838,24 +921,14 @@ void PyC_SetHomePath(const char *py_path_bundle)
/* OSX allow file/directory names to contain : character (represented as / in the Finder)
* but current Python lib (release 3.1.1) doesn't handle these correctly */
if (strchr(py_path_bundle, ':')) {
- printf(
- "Warning : Blender application is located in a path containing : or / chars\
- \nThis may make python import function fail\n");
- }
-# endif
-
-# if 0 /* disable for now [#31506] - campbell */
-# ifdef _WIN32
- /* cmake/MSVC debug build crashes without this, why only
- * in this case is unknown.. */
- {
- /*BLI_setenv("PYTHONPATH", py_path_bundle)*/;
+ fprintf(stderr,
+ "Warning! Blender application is located in a path containing ':' or '/' chars\n"
+ "This may make python import function fail\n");
}
-# endif
# endif
{
- static wchar_t py_path_bundle_wchar[1024];
+ wchar_t py_path_bundle_wchar[1024];
/* Can't use this, on linux gives bug: #23018,
* TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */
@@ -875,6 +948,12 @@ bool PyC_IsInterpreterActive(void)
return (PyThreadState_GetDict() != NULL);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name #Py_SetPythonHome Wrapper
+ * \{ */
+
/* Would be nice if python had this built in
* See: https://wiki.blender.org/wiki/Tools/Debugging/PyFromC
*/
@@ -1051,15 +1130,22 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
return result;
}
- else {
- PyErr_Format(PyExc_TypeError,
- "expected '%.200s' type found '%.200s' instead",
- type_name,
- Py_TYPE(value)->tp_name);
- return NULL;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "expected '%.200s' type found '%.200s' instead",
+ type_name,
+ Py_TYPE(value)->tp_name);
+ return NULL;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Flag Set Utilities (#PyC_FlagSet)
+ *
+ * Convert to/from Python set of strings to an int flag.
+ * \{ */
+
PyObject *PyC_FlagSet_AsString(PyC_FlagSet *item)
{
PyObject *py_items = PyList_New(0);
@@ -1160,6 +1246,12 @@ PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag)
return ret;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Run String (Evaluate to Primitive Types)
+ * \{ */
+
/**
* \return success
*
@@ -1323,6 +1415,8 @@ bool PyC_RunString_AsString(const char *imports[],
return PyC_RunString_AsStringAndSize(imports, expr, filename, r_value, &value_size);
}
+/** \} */
+
#endif /* #ifndef MATH_STANDALONE */
/* -------------------------------------------------------------------- */
@@ -1410,6 +1504,12 @@ uint32_t PyC_Long_AsU32(PyObject *value)
* PyC_Long_AsU64
*/
+#ifdef __GNUC__
+# pragma warning(pop)
+#endif
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Py_buffer Utils
*
@@ -1486,9 +1586,3 @@ bool PyC_StructFmt_type_is_bool(char format)
}
/** \} */
-
-#ifdef __GNUC__
-# pragma warning(pop)
-#endif
-
-/** \} */
diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c
index 1379c0e557a..da7674eb7f9 100644
--- a/source/blender/python/gpu/gpu_py_api.c
+++ b/source/blender/python/gpu/gpu_py_api.c
@@ -43,9 +43,9 @@
/** \name Utils to invalidate functions
* \{ */
-bool bpygpu_is_initialized_or_error(void)
+bool bpygpu_is_init_or_error(void)
{
- if (!GPU_is_initialized()) {
+ if (!GPU_is_init()) {
PyErr_SetString(PyExc_SystemError,
"GPU functions for drawing are not available in background mode");
diff --git a/source/blender/python/gpu/gpu_py_api.h b/source/blender/python/gpu/gpu_py_api.h
index 2360bba1f5d..b8f0cde129f 100644
--- a/source/blender/python/gpu/gpu_py_api.h
+++ b/source/blender/python/gpu/gpu_py_api.h
@@ -24,14 +24,14 @@ int bpygpu_ParsePrimType(PyObject *o, void *p);
PyObject *BPyInit_gpu(void);
-bool bpygpu_is_initialized_or_error(void);
+bool bpygpu_is_init_or_error(void);
#define BPYGPU_IS_INIT_OR_ERROR_OBJ \
- if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
+ if (UNLIKELY(!bpygpu_is_init_or_error())) { \
return NULL; \
} \
((void)0)
#define BPYGPU_IS_INIT_OR_ERROR_INT \
- if (UNLIKELY(!bpygpu_is_initialized_or_error())) { \
+ if (UNLIKELY(!bpygpu_is_init_or_error())) { \
return -1; \
} \
((void)0)
diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c
index b3df991cf12..01bccc57c7a 100644
--- a/source/blender/python/gpu/gpu_py_batch.c
+++ b/source/blender/python/gpu/gpu_py_batch.c
@@ -184,8 +184,7 @@ static PyObject *bpygpu_Batch_program_set(BPyGPUBatch *self, BPyGPUShader *py_sh
}
GPUShader *shader = py_shader->shader;
- GPU_batch_program_set(
- self->batch, GPU_shader_get_program(shader), GPU_shader_get_interface(shader));
+ GPU_batch_set_shader(self->batch, shader);
#ifdef USE_GPU_PY_REFERENCES
/* Remove existing user (if any), hold new user. */
@@ -223,15 +222,13 @@ static PyObject *bpygpu_Batch_draw(BPyGPUBatch *self, PyObject *args)
if (!PyArg_ParseTuple(args, "|O!:GPUBatch.draw", &BPyGPUShader_Type, &py_program)) {
return NULL;
}
- else if (py_program == NULL) {
+ if (py_program == NULL) {
if (!bpygpu_batch_is_program_or_error(self)) {
return NULL;
}
}
else if (self->batch->program != GPU_shader_get_program(py_program->shader)) {
- GPU_batch_program_set(self->batch,
- GPU_shader_get_program(py_program->shader),
- GPU_shader_get_interface(py_program->shader));
+ GPU_batch_set_shader(self->batch, py_program->shader);
}
GPU_batch_draw(self->batch);
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index dde1d13477f..cdbd3bc0b9c 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -118,22 +118,20 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type),
"get the dictionary from the function passed");
return NULL;
}
- else {
- /* set id */
- if (*dict_ptr == NULL) {
- *dict_ptr = PyDict_New();
- }
- PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
+ /* set id */
+ if (*dict_ptr == NULL) {
+ *dict_ptr = PyDict_New();
}
+ PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
+
Py_INCREF(value);
return value;
}
- else {
- PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError, "bpy.app.handlers.persistent expected a function");
+ return NULL;
}
/* dummy type because decorators can't be PyCFunctions */
diff --git a/source/blender/python/intern/bpy_capi_utils.c b/source/blender/python/intern/bpy_capi_utils.c
index 89ef2f40a30..27eea80f1f6 100644
--- a/source/blender/python/intern/bpy_capi_utils.c
+++ b/source/blender/python/intern/bpy_capi_utils.c
@@ -97,7 +97,10 @@ void BPy_reports_write_stdout(const ReportList *reports, const char *header)
}
}
-bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location)
+bool BPy_errors_to_report_ex(ReportList *reports,
+ const char *error_prefix,
+ const bool use_full,
+ const bool use_location)
{
PyObject *pystring;
@@ -124,40 +127,38 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo
return 0;
}
+ if (error_prefix == NULL) {
+ /* Not very helpful, better than nothing. */
+ error_prefix = "Python";
+ }
+
if (use_location) {
const char *filename;
int lineno;
- PyObject *pystring_format; /* workaround, see below */
- const char *cstring;
-
PyC_FileAndNum(&filename, &lineno);
if (filename == NULL) {
filename = "<unknown location>";
}
-#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */
BKE_reportf(reports,
RPT_ERROR,
- "%s\nlocation: %s:%d\n",
+ TIP_("%s: %s\nlocation: %s:%d\n"),
+ error_prefix,
_PyUnicode_AsString(pystring),
filename,
lineno);
-#else
- pystring_format = PyUnicode_FromFormat(
- TIP_("%s\nlocation: %s:%d\n"), _PyUnicode_AsString(pystring), filename, lineno);
-
- cstring = _PyUnicode_AsString(pystring_format);
- BKE_report(reports, RPT_ERROR, cstring);
-
- /* not exactly needed. just for testing */
- fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno);
- Py_DECREF(pystring_format); /* workaround */
-#endif
+ /* Not exactly needed. Useful for developers tracking down issues. */
+ fprintf(stderr,
+ TIP_("%s: %s\nlocation: %s:%d\n"),
+ error_prefix,
+ _PyUnicode_AsString(pystring),
+ filename,
+ lineno);
}
else {
- BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring));
+ BKE_reportf(reports, RPT_ERROR, "%s: %s", error_prefix, _PyUnicode_AsString(pystring));
}
Py_DECREF(pystring);
@@ -166,5 +167,5 @@ bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const boo
bool BPy_errors_to_report(ReportList *reports)
{
- return BPy_errors_to_report_ex(reports, true, true);
+ return BPy_errors_to_report_ex(reports, NULL, true, true);
}
diff --git a/source/blender/python/intern/bpy_capi_utils.h b/source/blender/python/intern/bpy_capi_utils.h
index c021ec14933..861b23190a2 100644
--- a/source/blender/python/intern/bpy_capi_utils.h
+++ b/source/blender/python/intern/bpy_capi_utils.h
@@ -42,8 +42,10 @@ char *BPy_enum_as_string(const struct EnumPropertyItem *item);
short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear);
void BPy_reports_write_stdout(const struct ReportList *reports, const char *header);
bool BPy_errors_to_report_ex(struct ReportList *reports,
+ const char *error_prefix,
const bool use_full,
const bool use_location);
+bool BPy_errors_to_report_brief_with_prefix(struct ReportList *reports, const char *error_prefix);
bool BPy_errors_to_report(struct ReportList *reports);
/* TODO - find a better solution! */
diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c
index 5e2162c9e2d..7fb4b0c469c 100644
--- a/source/blender/python/intern/bpy_driver.c
+++ b/source/blender/python/intern/bpy_driver.c
@@ -83,9 +83,8 @@ int bpy_pydriver_create_dict(void)
if (d == NULL) {
return -1;
}
- else {
- bpy_pydriver_Dict = d;
- }
+
+ bpy_pydriver_Dict = d;
/* import some modules: builtins, bpy, math, (Blender.noise)*/
PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
@@ -411,8 +410,10 @@ static PyObject *bpy_pydriver_depsgraph_as_pyobject(struct Depsgraph *depsgraph)
return pyrna_struct_CreatePyObject(&depsgraph_ptr);
}
-/* Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated
- * datablocks, and the current view layer and scene. See T75553. */
+/**
+ * Adds a variable 'depsgraph' to the driver variables. This can then be used to obtain evaluated
+ * data-blocks, and the current view layer and scene. See T75553.
+ */
static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars,
struct Depsgraph *depsgraph)
{
@@ -428,17 +429,18 @@ static void bpy_pydriver_namespace_add_depsgraph(PyObject *driver_vars,
}
}
-/* This evals py driver expressions, 'expr' is a Python expression that
- * should evaluate to a float number, which is returned.
+/**
+ * This evaluates Python driver expressions, `driver_orig->expression`
+ * is a Python expression that should evaluate to a float number, which is returned.
*
* (old)note: PyGILState_Ensure() isn't always called because python can call
* the bake operator which intern starts a thread which calls scene update
- * which does a driver update. to avoid a deadlock check PyC_IsInterpreterActive()
- * if PyGILState_Ensure() is needed - see [#27683]
+ * which does a driver update. to avoid a deadlock check #PyC_IsInterpreterActive()
+ * if #PyGILState_Ensure() is needed, see T27683.
*
- * (new)note: checking if python is running is not threadsafe [#28114]
+ * (new)note: checking if python is running is not thread-safe T28114
* now release the GIL on python operator execution instead, using
- * PyEval_SaveThread() / PyEval_RestoreThread() so we don't lock up blender.
+ * #PyEval_SaveThread() / #PyEval_RestoreThread() so we don't lock up blender.
*
* For copy-on-write we always cache expressions and write errors in the
* original driver, otherwise these would get freed while editing. Due to
@@ -677,11 +679,8 @@ float BPY_driver_exec(struct PathResolvedRNA *anim_rna,
if (isfinite(result)) {
return (float)result;
}
- else {
- fprintf(stderr,
- "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n",
- driver->expression,
- result);
- return 0.0f;
- }
+
+ fprintf(
+ stderr, "\tBPY_driver_eval() - driver '%s' evaluates to '%f'\n", driver->expression, result);
+ return 0.0f;
}
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 4fbe2db3ecd..c311041e4cb 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -258,11 +258,13 @@ void BPY_python_start(int argc, const char **argv)
PyThreadState *py_tstate = NULL;
const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL);
- /* not essential but nice to set our name */
- static wchar_t program_path_wchar[FILE_MAX]; /* python holds a reference */
- BLI_strncpy_wchar_from_utf8(
- program_path_wchar, BKE_appdir_program_path(), ARRAY_SIZE(program_path_wchar));
- Py_SetProgramName(program_path_wchar);
+ /* Not essential but nice to set our name. */
+ {
+ const char *program_path = BKE_appdir_program_path();
+ wchar_t program_path_wchar[FILE_MAX];
+ BLI_strncpy_wchar_from_utf8(program_path_wchar, program_path, ARRAY_SIZE(program_path_wchar));
+ Py_SetProgramName(program_path_wchar);
+ }
/* must run before python initializes */
PyImport_ExtendInittab(bpy_internal_modules);
@@ -621,8 +623,11 @@ void BPY_DECREF_RNA_INVALIDATE(void *pyob_ptr)
/**
* \return success
*/
-bool BPY_execute_string_as_number(
- bContext *C, const char *imports[], const char *expr, const bool verbose, double *r_value)
+bool BPY_execute_string_as_number(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ double *r_value)
{
PyGILState_STATE gilstate;
bool ok = true;
@@ -641,8 +646,8 @@ bool BPY_execute_string_as_number(
ok = PyC_RunString_AsNumber(imports, expr, "<expr as number>", r_value);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
}
else {
PyErr_Clear();
@@ -660,7 +665,7 @@ bool BPY_execute_string_as_number(
bool BPY_execute_string_as_string_and_size(bContext *C,
const char *imports[],
const char *expr,
- const bool verbose,
+ const char *report_prefix,
char **r_value,
size_t *r_value_size)
{
@@ -678,8 +683,8 @@ bool BPY_execute_string_as_string_and_size(bContext *C,
ok = PyC_RunString_AsStringAndSize(imports, expr, "<expr as str>", r_value, r_value_size);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), false, false, report_prefix);
}
else {
PyErr_Clear();
@@ -691,12 +696,15 @@ bool BPY_execute_string_as_string_and_size(bContext *C,
return ok;
}
-bool BPY_execute_string_as_string(
- bContext *C, const char *imports[], const char *expr, const bool verbose, char **r_value)
+bool BPY_execute_string_as_string(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ char **r_value)
{
size_t value_dummy_size;
return BPY_execute_string_as_string_and_size(
- C, imports, expr, verbose, r_value, &value_dummy_size);
+ C, imports, expr, report_prefix, r_value, &value_dummy_size);
}
/**
@@ -704,8 +712,11 @@ bool BPY_execute_string_as_string(
*
* \return success
*/
-bool BPY_execute_string_as_intptr(
- bContext *C, const char *imports[], const char *expr, const bool verbose, intptr_t *r_value)
+bool BPY_execute_string_as_intptr(bContext *C,
+ const char *imports[],
+ const char *expr,
+ const char *report_prefix,
+ intptr_t *r_value)
{
BLI_assert(r_value && expr);
PyGILState_STATE gilstate;
@@ -721,8 +732,8 @@ bool BPY_execute_string_as_intptr(
ok = PyC_RunString_AsIntPtr(imports, expr, "<expr as intptr>", r_value);
if (ok == false) {
- if (verbose) {
- BPy_errors_to_report_ex(CTX_wm_reports(C), false, false);
+ if (report_prefix != NULL) {
+ BPy_errors_to_report_ex(CTX_wm_reports(C), report_prefix, false, false);
}
else {
PyErr_Clear();
@@ -916,8 +927,11 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
/* TODO, reloading the module isn't functional at the moment. */
static void bpy_module_free(void *mod);
+
+/* Defined in 'creator.c' when building as a Python module. */
extern int main_python_enter(int argc, const char **argv);
extern void main_python_exit(void);
+
static struct PyModuleDef bpy_proxy_def = {
PyModuleDef_HEAD_INIT,
"bpy", /* m_name */
diff --git a/source/blender/python/intern/bpy_library_load.c b/source/blender/python/intern/bpy_library_load.c
index 05cbc9af601..bcf13b1d88f 100644
--- a/source/blender/python/intern/bpy_library_load.c
+++ b/source/blender/python/intern/bpy_library_load.c
@@ -244,21 +244,20 @@ static PyObject *bpy_lib_enter(BPy_Library *self)
}
return NULL;
}
- else {
- int i = 0, code;
- while ((code = BKE_idtype_idcode_iter_step(&i))) {
- if (BKE_idtype_idcode_is_linkable(code)) {
- const char *name_plural = BKE_idtype_idcode_to_name_plural(code);
- PyObject *str = PyUnicode_FromString(name_plural);
- PyObject *item;
-
- PyDict_SetItem(self->dict, str, item = PyList_New(0));
- Py_DECREF(item);
- PyDict_SetItem(from_dict, str, item = _bpy_names(self, code));
- Py_DECREF(item);
-
- Py_DECREF(str);
- }
+
+ int i = 0, code;
+ while ((code = BKE_idtype_idcode_iter_step(&i))) {
+ if (BKE_idtype_idcode_is_linkable(code)) {
+ const char *name_plural = BKE_idtype_idcode_to_name_plural(code);
+ PyObject *str = PyUnicode_FromString(name_plural);
+ PyObject *item;
+
+ PyDict_SetItem(self->dict, str, item = PyList_New(0));
+ Py_DECREF(item);
+ PyDict_SetItem(from_dict, str, item = _bpy_names(self, code));
+ Py_DECREF(item);
+
+ Py_DECREF(str);
}
}
@@ -393,65 +392,64 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
return NULL;
}
- else {
- Library *lib = mainl->curlib; /* newly added lib, assign before append end */
- BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL);
- BLO_blendhandle_close(self->blo_handle);
- self->blo_handle = NULL;
- GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__);
+ Library *lib = mainl->curlib; /* newly added lib, assign before append end */
+ BLO_library_link_end(mainl, &(self->blo_handle), self->flag, NULL, NULL, NULL, NULL);
+ BLO_blendhandle_close(self->blo_handle);
+ self->blo_handle = NULL;
- /* copied from wm_operator.c */
- {
- /* mark all library linked objects to be updated */
- BKE_main_lib_objects_recalc_all(bmain);
+ GHash *old_to_new_ids = BLI_ghash_ptr_new(__func__);
- /* append, rather than linking */
- if (do_append) {
- BKE_library_make_local(bmain, lib, old_to_new_ids, true, false);
- }
+ /* copied from wm_operator.c */
+ {
+ /* mark all library linked objects to be updated */
+ BKE_main_lib_objects_recalc_all(bmain);
+
+ /* append, rather than linking */
+ if (do_append) {
+ BKE_library_make_local(bmain, lib, old_to_new_ids, true, false);
}
+ }
- BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
+ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
- /* finally swap the capsules for real bpy objects
- * important since BLO_library_append_end initializes NodeTree types used by srna->refine */
+ /* finally swap the capsules for real bpy objects
+ * important since BLO_library_append_end initializes NodeTree types used by srna->refine */
#ifdef USE_RNA_DATABLOCKS
- {
- int idcode_step = 0, idcode;
- while ((idcode = BKE_idtype_idcode_iter_step(&idcode_step))) {
- if (BKE_idtype_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
- const char *name_plural = BKE_idtype_idcode_to_name_plural(idcode);
- PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
- if (ls && PyList_Check(ls)) {
- Py_ssize_t size = PyList_GET_SIZE(ls);
- Py_ssize_t i;
- PyObject *item;
-
- for (i = 0; i < size; i++) {
- item = PyList_GET_ITEM(ls, i);
- if (PyCapsule_CheckExact(item)) {
- PointerRNA id_ptr;
- ID *id;
-
- id = PyCapsule_GetPointer(item, NULL);
- id = BLI_ghash_lookup_default(old_to_new_ids, id, id);
- Py_DECREF(item);
-
- RNA_id_pointer_create(id, &id_ptr);
- item = pyrna_struct_CreatePyObject(&id_ptr);
- PyList_SET_ITEM(ls, i, item);
- }
+ {
+ int idcode_step = 0, idcode;
+ while ((idcode = BKE_idtype_idcode_iter_step(&idcode_step))) {
+ if (BKE_idtype_idcode_is_linkable(idcode) && (idcode != ID_WS || do_append)) {
+ const char *name_plural = BKE_idtype_idcode_to_name_plural(idcode);
+ PyObject *ls = PyDict_GetItemString(self->dict, name_plural);
+ if (ls && PyList_Check(ls)) {
+ Py_ssize_t size = PyList_GET_SIZE(ls);
+ Py_ssize_t i;
+ PyObject *item;
+
+ for (i = 0; i < size; i++) {
+ item = PyList_GET_ITEM(ls, i);
+ if (PyCapsule_CheckExact(item)) {
+ PointerRNA id_ptr;
+ ID *id;
+
+ id = PyCapsule_GetPointer(item, NULL);
+ id = BLI_ghash_lookup_default(old_to_new_ids, id, id);
+ Py_DECREF(item);
+
+ RNA_id_pointer_create(id, &id_ptr);
+ item = pyrna_struct_CreatePyObject(&id_ptr);
+ PyList_SET_ITEM(ls, i, item);
}
}
}
}
}
+ }
#endif /* USE_RNA_DATABLOCKS */
- BLI_ghash_free(old_to_new_ids, NULL, NULL);
- Py_RETURN_NONE;
- }
+ BLI_ghash_free(old_to_new_ids, NULL, NULL);
+ Py_RETURN_NONE;
}
static PyObject *bpy_lib_dir(BPy_Library *self)
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 830acd987d9..66c67ca061c 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1408,9 +1408,8 @@ static bool py_long_as_int(PyObject *py_long, int *r_int)
*r_int = (int)PyLong_AS_LONG(py_long);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
#if 0
@@ -1716,16 +1715,15 @@ static int bpy_prop_callback_check(PyObject *py_func, const char *keyword, int a
Py_TYPE(py_func)->tp_name);
return -1;
}
- else {
- PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
- if (f_code->co_argcount != argcount) {
- PyErr_Format(PyExc_TypeError,
- "%s keyword: expected a function taking %d arguments, not %d",
- keyword,
- argcount,
- f_code->co_argcount);
- return -1;
- }
+
+ PyCodeObject *f_code = (PyCodeObject *)PyFunction_GET_CODE(py_func);
+ if (f_code->co_argcount != argcount) {
+ PyErr_Format(PyExc_TypeError,
+ "%s keyword: expected a function taking %d arguments, not %d",
+ keyword,
+ argcount,
+ f_code->co_argcount);
+ return -1;
}
}
@@ -1981,7 +1979,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop,
Py_DECREF(args); \
return ret; \
} \
- else if (PyTuple_GET_SIZE(args) > 1) { \
+ if (PyTuple_GET_SIZE(args) > 1) { \
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
return NULL; \
} \
@@ -3537,7 +3535,7 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
Py_DECREF(args);
return ret;
}
- else if (PyTuple_GET_SIZE(args) > 1) {
+ if (PyTuple_GET_SIZE(args) > 1) {
PyErr_SetString(PyExc_ValueError, "expected one positional arg, one keyword arg");
return NULL;
}
@@ -3546,27 +3544,27 @@ static PyObject *BPy_RemoveProperty(PyObject *self, PyObject *args, PyObject *kw
if (srna == NULL && PyErr_Occurred()) {
return NULL; /* self's type was compatible but error getting the srna */
}
- else if (srna == NULL) {
+ if (srna == NULL) {
PyErr_SetString(PyExc_TypeError, "RemoveProperty(): struct rna not available for this type");
return NULL;
}
- else {
- const char *id = NULL;
- static const char *_keywords[] = {
- "attr",
- NULL,
- };
- static _PyArg_Parser _parser = {"s:RemoveProperty", _keywords, 0};
- if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) {
- return NULL;
- }
+ const char *id = NULL;
- if (RNA_def_property_free_identifier(srna, id) != 1) {
- PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
- return NULL;
- }
+ static const char *_keywords[] = {
+ "attr",
+ NULL,
+ };
+ static _PyArg_Parser _parser = {"s:RemoveProperty", _keywords, 0};
+ if (!_PyArg_ParseTupleAndKeywordsFast(args, kw, &_parser, &id)) {
+ return NULL;
+ }
+
+ if (RNA_def_property_free_identifier(srna, id) != 1) {
+ PyErr_Format(PyExc_TypeError, "RemoveProperty(): '%s' not a defined dynamic property", id);
+ return NULL;
}
+
Py_RETURN_NONE;
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 893832b61b6..955a24bc880 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -987,24 +987,23 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self)
PyErr_SetString(PyExc_RuntimeError, "could not use property type, internal error");
return NULL;
}
- else {
- /* This should never fail. */
- int len = -1;
- char *c = type_fmt;
- while ((*c++ = tolower(*type_id++))) {
- }
+ /* This should never fail. */
+ int len = -1;
+ char *c = type_fmt;
- if (type == PROP_COLLECTION) {
- len = pyrna_prop_collection_length(self);
- }
- else if (RNA_property_array_check(self->prop)) {
- len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
- }
+ while ((*c++ = tolower(*type_id++))) {
+ }
- if (len != -1) {
- sprintf(--c, "[%d]", len);
- }
+ if (type == PROP_COLLECTION) {
+ len = pyrna_prop_collection_length(self);
+ }
+ else if (RNA_property_array_check(self->prop)) {
+ len = pyrna_prop_array_length((BPy_PropertyArrayRNA *)self);
+ }
+
+ if (len != -1) {
+ sprintf(--c, "[%d]", len);
}
/* If a pointer, try to print name of pointer target too. */
@@ -1246,17 +1245,16 @@ static int pyrna_string_to_enum(
Py_TYPE(item)->tp_name);
return -1;
}
- else {
- if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) {
- const char *enum_str = pyrna_enum_as_string(ptr, prop);
- PyErr_Format(PyExc_TypeError,
- "%.200s enum \"%.200s\" not found in (%s)",
- error_prefix,
- param,
- enum_str);
- MEM_freeN((void *)enum_str);
- return -1;
- }
+
+ if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, r_value)) {
+ const char *enum_str = pyrna_enum_as_string(ptr, prop);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s enum \"%.200s\" not found in (%s)",
+ error_prefix,
+ param,
+ enum_str);
+ MEM_freeN((void *)enum_str);
+ return -1;
}
return 0;
@@ -1715,14 +1713,14 @@ static int pyrna_py_to_prop(
Py_TYPE(value)->tp_name);
return -1;
}
+
+ if (data) {
+ *((bool *)data) = param;
+ }
else {
- if (data) {
- *((bool *)data) = param;
- }
- else {
- RNA_property_boolean_set(ptr, prop, param);
- }
+ RNA_property_boolean_set(ptr, prop, param);
}
+
break;
}
case PROP_INT: {
@@ -1737,7 +1735,7 @@ static int pyrna_py_to_prop(
RNA_property_identifier(prop));
return -1;
}
- else if (param == -1 && PyErr_Occurred()) {
+ if (param == -1 && PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s expected an int type, not %.200s",
error_prefix,
@@ -1746,16 +1744,16 @@ static int pyrna_py_to_prop(
Py_TYPE(value)->tp_name);
return -1;
}
+
+ int param_i = (int)param;
+ if (data) {
+ RNA_property_int_clamp(ptr, prop, &param_i);
+ *((int *)data) = param_i;
+ }
else {
- int param_i = (int)param;
- if (data) {
- RNA_property_int_clamp(ptr, prop, &param_i);
- *((int *)data) = param_i;
- }
- else {
- RNA_property_int_set(ptr, prop, param_i);
- }
+ RNA_property_int_set(ptr, prop, param_i);
}
+
break;
}
case PROP_FLOAT: {
@@ -1769,15 +1767,15 @@ static int pyrna_py_to_prop(
Py_TYPE(value)->tp_name);
return -1;
}
+
+ if (data) {
+ RNA_property_float_clamp(ptr, prop, (float *)&param);
+ *((float *)data) = param;
+ }
else {
- if (data) {
- RNA_property_float_clamp(ptr, prop, (float *)&param);
- *((float *)data) = param;
- }
- else {
- RNA_property_float_set(ptr, prop, param);
- }
+ RNA_property_float_set(ptr, prop, param);
}
+
break;
}
case PROP_STRING: {
@@ -1835,19 +1833,18 @@ static int pyrna_py_to_prop(
return -1;
}
- else {
- if (data) {
- if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
- BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
- }
- else {
- *((char **)data) = (char *)param;
- }
+
+ if (data) {
+ if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
+ BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
}
else {
- RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value));
+ *((char **)data) = (char *)param;
}
}
+ else {
+ RNA_property_string_set_bytes(ptr, prop, param, PyBytes_Size(value));
+ }
}
else {
/* Unicode String. */
@@ -1886,22 +1883,22 @@ static int pyrna_py_to_prop(
return -1;
}
- else {
- /* Same as bytes. */
- /* XXX, this is suspect, but needed for function calls,
- * need to see if there's a better way. */
- if (data) {
- if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
- BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
- }
- else {
- *((char **)data) = (char *)param;
- }
+
+ /* Same as bytes. */
+ /* XXX, this is suspect, but needed for function calls,
+ * need to see if there's a better way. */
+ if (data) {
+ if (RNA_property_flag(prop) & PROP_THICK_WRAP) {
+ BLI_strncpy((char *)data, (char *)param, RNA_property_string_maxlength(prop));
}
else {
- RNA_property_string_set(ptr, prop, param);
+ *((char **)data) = (char *)param;
}
}
+ else {
+ RNA_property_string_set(ptr, prop, param);
+ }
+
#ifdef USE_STRING_COERCE
Py_XDECREF(value_coerce);
#endif /* USE_STRING_COERCE */
@@ -1971,7 +1968,7 @@ static int pyrna_py_to_prop(
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
}
- else if (base_type == &RNA_GizmoProperties) {
+ if (base_type == &RNA_GizmoProperties) {
PointerRNA opptr = RNA_property_pointer_get(ptr, prop);
return pyrna_pydict_to_props(&opptr, value, false, error_prefix);
}
@@ -2008,7 +2005,7 @@ static int pyrna_py_to_prop(
Py_XDECREF(value_new);
return -1;
}
- else if ((flag & PROP_NEVER_NULL) && value == Py_None) {
+ if ((flag & PROP_NEVER_NULL) && value == Py_None) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s does not support a 'None' assignment %.200s type",
error_prefix,
@@ -2018,8 +2015,8 @@ static int pyrna_py_to_prop(
Py_XDECREF(value_new);
return -1;
}
- else if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) &&
- ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) {
+ if ((value != Py_None) && ((flag & PROP_ID_SELF_CHECK) &&
+ ptr->owner_id == ((BPy_StructRNA *)value)->ptr.owner_id)) {
PyErr_Format(PyExc_TypeError,
"%.200s %.200s.%.200s ID type does not support assignment to itself",
error_prefix,
@@ -2028,85 +2025,84 @@ static int pyrna_py_to_prop(
Py_XDECREF(value_new);
return -1;
}
- else {
- BPy_StructRNA *param = (BPy_StructRNA *)value;
- bool raise_error = false;
- if (data) {
- if (flag_parameter & PARM_RNAPTR) {
- if (flag & PROP_THICK_WRAP) {
- if (value == Py_None) {
- memset(data, 0, sizeof(PointerRNA));
- }
- else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
- *((PointerRNA *)data) = param->ptr;
- }
- else {
- raise_error = true;
- }
+ BPy_StructRNA *param = (BPy_StructRNA *)value;
+ bool raise_error = false;
+ if (data) {
+
+ if (flag_parameter & PARM_RNAPTR) {
+ if (flag & PROP_THICK_WRAP) {
+ if (value == Py_None) {
+ memset(data, 0, sizeof(PointerRNA));
+ }
+ else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
+ *((PointerRNA *)data) = param->ptr;
}
else {
- /* For function calls, we sometimes want to pass the 'ptr' directly,
- * but watch out that it remains valid!
- * We could possibly support this later if needed. */
- BLI_assert(value_new == NULL);
- if (value == Py_None) {
- *((void **)data) = NULL;
- }
- else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
- *((PointerRNA **)data) = &param->ptr;
- }
- else {
- raise_error = true;
- }
+ raise_error = true;
}
}
- else if (value == Py_None) {
- *((void **)data) = NULL;
- }
- else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
- *((void **)data) = param->ptr.data;
- }
else {
- raise_error = true;
+ /* For function calls, we sometimes want to pass the 'ptr' directly,
+ * but watch out that it remains valid!
+ * We could possibly support this later if needed. */
+ BLI_assert(value_new == NULL);
+ if (value == Py_None) {
+ *((void **)data) = NULL;
+ }
+ else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
+ *((PointerRNA **)data) = &param->ptr;
+ }
+ else {
+ raise_error = true;
+ }
}
}
+ else if (value == Py_None) {
+ *((void **)data) = NULL;
+ }
+ else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
+ *((void **)data) = param->ptr.data;
+ }
else {
- /* Data == NULL, assign to RNA. */
- if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) {
- ReportList reports;
- BKE_reports_init(&reports, RPT_STORE);
- RNA_property_pointer_set(
- ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports);
- int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
- if (err == -1) {
- Py_XDECREF(value_new);
- return -1;
- }
- }
- else {
- raise_error = true;
+ raise_error = true;
+ }
+ }
+ else {
+ /* Data == NULL, assign to RNA. */
+ if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type)) {
+ ReportList reports;
+ BKE_reports_init(&reports, RPT_STORE);
+ RNA_property_pointer_set(
+ ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr, &reports);
+ int err = (BPy_reports_to_error(&reports, PyExc_RuntimeError, true));
+ if (err == -1) {
+ Py_XDECREF(value_new);
+ return -1;
}
}
+ else {
+ raise_error = true;
+ }
+ }
- if (raise_error) {
- if (pyrna_struct_validity_check(param) == -1) {
- /* Error set. */
- }
- else {
- PointerRNA tmp;
- RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
- PyErr_Format(PyExc_TypeError,
- "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
- error_prefix,
- RNA_struct_identifier(ptr->type),
- RNA_property_identifier(prop),
- RNA_struct_identifier(tmp.type),
- RNA_struct_identifier(param->ptr.type));
- }
- Py_XDECREF(value_new);
- return -1;
+ if (raise_error) {
+ if (pyrna_struct_validity_check(param) == -1) {
+ /* Error set. */
}
+ else {
+ PointerRNA tmp;
+ RNA_pointer_create(NULL, ptr_type, NULL, &tmp);
+ PyErr_Format(PyExc_TypeError,
+ "%.200s %.200s.%.200s expected a %.200s type, not %.200s",
+ error_prefix,
+ RNA_struct_identifier(ptr->type),
+ RNA_property_identifier(prop),
+ RNA_struct_identifier(tmp.type),
+ RNA_struct_identifier(param->ptr.type));
+ }
+ Py_XDECREF(value_new);
+ return -1;
}
Py_XDECREF(value_new);
@@ -2295,9 +2291,8 @@ static Py_ssize_t pyrna_prop_array_length(BPy_PropertyArrayRNA *self)
if (RNA_property_array_dimension(&self->ptr, self->prop, NULL) > 1) {
return RNA_property_multi_array_length(&self->ptr, self->prop, self->arraydim);
}
- else {
- return RNA_property_array_length(&self->ptr, self->prop);
- }
+
+ return RNA_property_array_length(&self->ptr, self->prop);
}
static Py_ssize_t pyrna_prop_collection_length(BPy_PropertyRNA *self)
@@ -2356,25 +2351,24 @@ static PyObject *pyrna_prop_collection_subscript_int(BPy_PropertyRNA *self, Py_s
if (RNA_property_collection_lookup_int(&self->ptr, self->prop, keynum_abs, &newptr)) {
return pyrna_struct_CreatePyObject(&newptr);
}
- else {
- const int len = RNA_property_collection_length(&self->ptr, self->prop);
- if (keynum_abs >= len) {
- PyErr_Format(PyExc_IndexError,
- "bpy_prop_collection[index]: "
- "index %d out of range, size %d",
- keynum,
- len);
- }
- else {
- PyErr_Format(PyExc_RuntimeError,
- "bpy_prop_collection[index]: internal error, "
- "valid index %d given in %d sized collection, but value not found",
- keynum_abs,
- len);
- }
- return NULL;
+ const int len = RNA_property_collection_length(&self->ptr, self->prop);
+ if (keynum_abs >= len) {
+ PyErr_Format(PyExc_IndexError,
+ "bpy_prop_collection[index]: "
+ "index %d out of range, size %d",
+ keynum,
+ len);
+ }
+ else {
+ PyErr_Format(PyExc_RuntimeError,
+ "bpy_prop_collection[index]: internal error, "
+ "valid index %d given in %d sized collection, but value not found",
+ keynum_abs,
+ len);
}
+
+ return NULL;
}
/* Values type must have been already checked. */
@@ -2473,79 +2467,76 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
PyTuple_GET_SIZE(key));
return -1;
}
- else if (self->ptr.type != &RNA_BlendData) {
+ if (self->ptr.type != &RNA_BlendData) {
PyErr_Format(PyExc_KeyError,
"%s: is only valid for bpy.data collections, not %.200s",
err_prefix,
RNA_struct_identifier(self->ptr.type));
return -1;
}
- else if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
+ if ((keyname = _PyUnicode_AsString(PyTuple_GET_ITEM(key, 0))) == NULL) {
PyErr_Format(PyExc_KeyError,
"%s: id must be a string, not %.200s",
err_prefix,
Py_TYPE(PyTuple_GET_ITEM(key, 0))->tp_name);
return -1;
}
- else {
- PyObject *keylib = PyTuple_GET_ITEM(key, 1);
- Library *lib;
- bool found = false;
-
- if (keylib == Py_None) {
- lib = NULL;
- }
- else if (PyUnicode_Check(keylib)) {
- Main *bmain = self->ptr.data;
- const char *keylib_str = _PyUnicode_AsString(keylib);
- lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath));
- if (lib == NULL) {
- if (err_not_found) {
- PyErr_Format(PyExc_KeyError,
- "%s: lib name '%.240s' "
- "does not reference a valid library",
- err_prefix,
- keylib_str);
- return -1;
- }
- else {
- return 0;
- }
+
+ PyObject *keylib = PyTuple_GET_ITEM(key, 1);
+ Library *lib;
+ bool found = false;
+
+ if (keylib == Py_None) {
+ lib = NULL;
+ }
+ else if (PyUnicode_Check(keylib)) {
+ Main *bmain = self->ptr.data;
+ const char *keylib_str = _PyUnicode_AsString(keylib);
+ lib = BLI_findstring(&bmain->libraries, keylib_str, offsetof(Library, filepath));
+ if (lib == NULL) {
+ if (err_not_found) {
+ PyErr_Format(PyExc_KeyError,
+ "%s: lib name '%.240s' "
+ "does not reference a valid library",
+ err_prefix,
+ keylib_str);
+ return -1;
}
+
+ return 0;
}
- else {
- PyErr_Format(PyExc_KeyError,
- "%s: lib must be a string or None, not %.200s",
- err_prefix,
- Py_TYPE(keylib)->tp_name);
- return -1;
- }
+ }
+ else {
+ PyErr_Format(PyExc_KeyError,
+ "%s: lib must be a string or None, not %.200s",
+ err_prefix,
+ Py_TYPE(keylib)->tp_name);
+ return -1;
+ }
- /* lib is either a valid pointer or NULL,
- * either way can do direct comparison with id.lib */
+ /* lib is either a valid pointer or NULL,
+ * either way can do direct comparison with id.lib */
- RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
- ID *id = itemptr.data; /* Always an ID. */
- if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
- found = true;
- if (r_ptr) {
- *r_ptr = itemptr;
- }
- break;
+ RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop) {
+ ID *id = itemptr.data; /* Always an ID. */
+ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
+ found = true;
+ if (r_ptr) {
+ *r_ptr = itemptr;
}
+ break;
}
- RNA_PROP_END;
+ }
+ RNA_PROP_END;
- /* We may want to fail silently as with collection.get(). */
- if ((found == false) && err_not_found) {
- /* Only runs for getitem access so use fixed string. */
- PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found");
- return -1;
- }
- else {
- return found; /* 1 / 0, no exception. */
- }
+ /* We may want to fail silently as with collection.get(). */
+ if ((found == false) && err_not_found) {
+ /* Only runs for getitem access so use fixed string. */
+ PyErr_SetString(PyExc_KeyError, "bpy_prop_collection[key, lib]: not found");
+ return -1;
}
+
+ return found; /* 1 / 0, no exception. */
}
static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *self,
@@ -2560,9 +2551,8 @@ static PyObject *pyrna_prop_collection_subscript_str_lib_pair(BPy_PropertyRNA *s
if (contains == 1) {
return pyrna_struct_CreatePyObject(&ptr);
}
- else {
- return NULL;
- }
+
+ return NULL;
}
static PyObject *pyrna_prop_collection_subscript_slice(BPy_PropertyRNA *self,
@@ -2707,7 +2697,7 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
if (PyUnicode_Check(key)) {
return pyrna_prop_collection_subscript_str(self, _PyUnicode_AsString(key));
}
- else if (PyIndex_Check(key)) {
+ if (PyIndex_Check(key)) {
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) {
return NULL;
@@ -2715,62 +2705,59 @@ static PyObject *pyrna_prop_collection_subscript(BPy_PropertyRNA *self, PyObject
return pyrna_prop_collection_subscript_int(self, i);
}
- else if (PySlice_Check(key)) {
+ if (PySlice_Check(key)) {
PySliceObject *key_slice = (PySliceObject *)key;
Py_ssize_t step = 1;
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
- else if (step != 1) {
+ if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_collection[slice]: slice steps not supported");
return NULL;
}
- else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+ if (key_slice->start == Py_None && key_slice->stop == Py_None) {
return pyrna_prop_collection_subscript_slice(self, 0, PY_SSIZE_T_MAX);
}
- else {
- Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
- if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
- return NULL;
- }
- if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
- return NULL;
- }
+ Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX;
- if (start < 0 || stop < 0) {
- /* Only get the length for negative values. */
- Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
- if (start < 0) {
- start += len;
- }
- if (stop < 0) {
- stop += len;
- }
- }
+ /* Avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */
+ if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) {
+ return NULL;
+ }
+ if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) {
+ return NULL;
+ }
- if (stop - start <= 0) {
- return PyList_New(0);
+ if (start < 0 || stop < 0) {
+ /* Only get the length for negative values. */
+ Py_ssize_t len = (Py_ssize_t)RNA_property_collection_length(&self->ptr, self->prop);
+ if (start < 0) {
+ start += len;
}
- else {
- return pyrna_prop_collection_subscript_slice(self, start, stop);
+ if (stop < 0) {
+ stop += len;
}
}
+
+ if (stop - start <= 0) {
+ return PyList_New(0);
+ }
+
+ return pyrna_prop_collection_subscript_slice(self, start, stop);
}
- else if (PyTuple_Check(key)) {
+ if (PyTuple_Check(key)) {
/* Special case, for ID datablocks we. */
return pyrna_prop_collection_subscript_str_lib_pair(
self, key, "bpy_prop_collection[id, lib]", true);
}
- else {
- PyErr_Format(PyExc_TypeError,
- "bpy_prop_collection[key]: invalid key, "
- "must be a string or an int, not %.200s",
- Py_TYPE(key)->tp_name);
- return NULL;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key]: invalid key, "
+ "must be a string or an int, not %.200s",
+ Py_TYPE(key)->tp_name);
+ return NULL;
}
/* generic check to see if a PyObject is compatible with a collection
@@ -2786,18 +2773,17 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val
"this collection doesn't support None assignment");
return -1;
}
- else {
- return 0; /* None is OK. */
- }
+
+ return 0; /* None is OK. */
}
- else if (BPy_StructRNA_Check(value) == 0) {
+ if (BPy_StructRNA_Check(value) == 0) {
PyErr_Format(PyExc_TypeError,
"bpy_prop_collection[key] = value: invalid, "
"expected a StructRNA type or None, not a %.200s",
Py_TYPE(value)->tp_name);
return -1;
}
- else if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
+ if ((prop_srna = RNA_property_pointer_type(&self->ptr, self->prop))) {
StructRNA *value_srna = ((BPy_StructRNA *)value)->ptr.type;
if (RNA_struct_is_a(value_srna, prop_srna) == 0) {
PyErr_Format(PyExc_TypeError,
@@ -2807,9 +2793,8 @@ static int pyrna_prop_collection_type_check(BPy_PropertyRNA *self, PyObject *val
RNA_struct_identifier(value_srna));
return -1;
}
- else {
- return 0; /* OK, this is the correct type! */
- }
+
+ return 0; /* OK, this is the correct type! */
}
PyErr_Format(PyExc_TypeError,
@@ -2831,7 +2816,7 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
PyErr_SetString(PyExc_TypeError, "del bpy_prop_collection[key]: not supported");
return -1;
}
- else if (pyrna_prop_collection_type_check(self, value) == -1) {
+ if (pyrna_prop_collection_type_check(self, value) == -1) {
return -1; /* Exception is set. */
}
@@ -2895,13 +2880,12 @@ static int pyrna_prop_collection_ass_subscript(BPy_PropertyRNA *self,
}
}
#endif
- else {
- PyErr_Format(PyExc_TypeError,
- "bpy_prop_collection[key]: invalid key, "
- "must be a string or an int, not %.200s",
- Py_TYPE(key)->tp_name);
- return -1;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop_collection[key]: invalid key, "
+ "must be a string or an int, not %.200s",
+ Py_TYPE(key)->tp_name);
+ return -1;
}
static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject *key)
@@ -2921,43 +2905,40 @@ static PyObject *pyrna_prop_array_subscript(BPy_PropertyArrayRNA *self, PyObject
}
return pyrna_prop_array_subscript_int(self, i);
}
- else if (PySlice_Check(key)) {
+ if (PySlice_Check(key)) {
Py_ssize_t step = 1;
PySliceObject *key_slice = (PySliceObject *)key;
if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) {
return NULL;
}
- else if (step != 1) {
+ if (step != 1) {
PyErr_SetString(PyExc_TypeError, "bpy_prop_array[slice]: slice steps not supported");
return NULL;
}
- else if (key_slice->start == Py_None && key_slice->stop == Py_None) {
+ if (key_slice->start == Py_None && key_slice->stop == Py_None) {
/* Note: no significant advantage with optimizing [:] slice as with collections,
* but include here for consistency with collection slice func */
Py_ssize_t len = (Py_ssize_t)pyrna_prop_array_length(self);
return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, 0, len, len);
}
- else {
- int len = pyrna_prop_array_length(self);
- Py_ssize_t start, stop, slicelength;
- if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
+ int len = pyrna_prop_array_length(self);
+ Py_ssize_t start, stop, slicelength;
- if (slicelength <= 0) {
- return PyTuple_New(0);
- }
- else {
- return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
- }
+ if (PySlice_GetIndicesEx(key, len, &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
}
+
+ if (slicelength <= 0) {
+ return PyTuple_New(0);
+ }
+
+ return pyrna_prop_array_subscript_slice(self, &self->ptr, self->prop, start, stop, len);
}
- else {
- PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError, "bpy_prop_array[key]: invalid key, key must be an int");
+ return NULL;
}
/**
@@ -2972,7 +2953,7 @@ static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, in
"element in assignment is not a sequence type"))) {
return NULL;
}
- else if (PySequence_Fast_GET_SIZE(value_fast) != length) {
+ if (PySequence_Fast_GET_SIZE(value_fast) != length) {
Py_DECREF(value_fast);
PyErr_SetString(PyExc_ValueError,
"bpy_prop_array[slice] = value: "
@@ -2980,9 +2961,8 @@ static PyObject *prop_subscript_ass_array_slice__as_seq_fast(PyObject *value, in
return NULL;
}
- else {
- return value_fast;
- }
+
+ return value_fast;
}
static int prop_subscript_ass_array_slice__float_recursive(
@@ -3005,17 +2985,16 @@ static int prop_subscript_ass_array_slice__float_recursive(
}
return index;
}
- else {
- BLI_assert(totdim == 1);
- const float min = range[0], max = range[1];
- int i;
- for (i = 0; i != length; i++) {
- float v = PyFloat_AsDouble(value_items[i]);
- CLAMP(v, min, max);
- value[i] = v;
- }
- return i;
+
+ BLI_assert(totdim == 1);
+ const float min = range[0], max = range[1];
+ int i;
+ for (i = 0; i != length; i++) {
+ float v = PyFloat_AsDouble(value_items[i]);
+ CLAMP(v, min, max);
+ value[i] = v;
}
+ return i;
}
static int prop_subscript_ass_array_slice__int_recursive(
@@ -3038,17 +3017,16 @@ static int prop_subscript_ass_array_slice__int_recursive(
}
return index;
}
- else {
- BLI_assert(totdim == 1);
- const int min = range[0], max = range[1];
- int i;
- for (i = 0; i != length; i++) {
- int v = PyLong_AsLong(value_items[i]);
- CLAMP(v, min, max);
- value[i] = v;
- }
- return i;
+
+ BLI_assert(totdim == 1);
+ const int min = range[0], max = range[1];
+ int i;
+ for (i = 0; i != length; i++) {
+ int v = PyLong_AsLong(value_items[i]);
+ CLAMP(v, min, max);
+ value[i] = v;
}
+ return i;
}
static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items,
@@ -3073,15 +3051,14 @@ static int prop_subscript_ass_array_slice__bool_recursive(PyObject **value_items
}
return index;
}
- else {
- BLI_assert(totdim == 1);
- int i;
- for (i = 0; i != length; i++) {
- int v = PyLong_AsLong(value_items[i]);
- value[i] = v;
- }
- return i;
+
+ BLI_assert(totdim == 1);
+ int i;
+ for (i = 0; i != length; i++) {
+ int v = PyLong_AsLong(value_items[i]);
+ value[i] = v;
}
+ return i;
}
/* Could call `pyrna_py_to_prop_array_index(self, i, value)` in a loop, but it is slow. */
@@ -3364,23 +3341,21 @@ static int pyrna_prop_collection_contains(BPy_PropertyRNA *self, PyObject *key)
return pyrna_prop_collection_subscript_str_lib_pair_ptr(
self, key, "(id, lib) in bpy_prop_collection", false, NULL);
}
- else {
-
- /* Key in dict style check. */
- const char *keyname = _PyUnicode_AsString(key);
- if (keyname == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
- return -1;
- }
+ /* Key in dict style check. */
+ const char *keyname = _PyUnicode_AsString(key);
- if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
- return 1;
- }
+ if (keyname == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "bpy_prop_collection.__contains__: expected a string or a tuple of strings");
+ return -1;
+ }
- return 0;
+ if (RNA_property_collection_lookup_string(&self->ptr, self->prop, keyname, &newptr)) {
+ return 1;
}
+
+ return 0;
}
static int pyrna_struct_contains(BPy_StructRNA *self, PyObject *value)
@@ -3821,30 +3796,25 @@ static PyObject *pyrna_struct_path_resolve(BPy_StructRNA *self, PyObject *args)
path);
return NULL;
}
- else {
- return pyrna_array_index(&r_ptr, r_prop, index);
- }
+
+ return pyrna_array_index(&r_ptr, r_prop, index);
}
- else {
- if (coerce == Py_False) {
- return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
- }
- else {
- return pyrna_prop_to_py(&r_ptr, r_prop);
- }
+
+ if (coerce == Py_False) {
+ return pyrna_prop_CreatePyObject(&r_ptr, r_prop);
}
+
+ return pyrna_prop_to_py(&r_ptr, r_prop);
}
- else {
- return pyrna_struct_CreatePyObject(&r_ptr);
- }
- }
- else {
- PyErr_Format(PyExc_ValueError,
- "%.200s.path_resolve(\"%.200s\") could not be resolved",
- RNA_struct_identifier(self->ptr.type),
- path);
- return NULL;
+
+ return pyrna_struct_CreatePyObject(&r_ptr);
}
+
+ PyErr_Format(PyExc_ValueError,
+ "%.200s.path_resolve(\"%.200s\") could not be resolved",
+ RNA_struct_identifier(self->ptr.type),
+ path);
+ return NULL;
}
PyDoc_STRVAR(pyrna_struct_path_from_id_doc,
@@ -3954,22 +3924,21 @@ static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self)
RNA_property_identifier(self->prop));
return NULL;
}
- else {
- PyObject *ret;
- char buf_fixed[256], *buf;
- int buf_len;
- buf = RNA_property_string_get_alloc(
- &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
+ PyObject *ret;
+ char buf_fixed[256], *buf;
+ int buf_len;
- ret = PyBytes_FromStringAndSize(buf, buf_len);
+ buf = RNA_property_string_get_alloc(
+ &self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len);
- if (buf_fixed != buf) {
- MEM_freeN(buf);
- }
+ ret = PyBytes_FromStringAndSize(buf, buf_len);
- return ret;
+ if (buf_fixed != buf) {
+ MEM_freeN(buf);
}
+
+ return ret;
}
PyDoc_STRVAR(pyrna_prop_update_doc,
@@ -4478,7 +4447,7 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
PyErr_SetString(PyExc_AttributeError, "bpy_struct: __setattr__ must be a string");
return -1;
}
- else if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) {
+ if (name[0] != '_' && (prop = RNA_struct_find_property(&self->ptr, name))) {
if (!RNA_property_editable_flag(&self->ptr, prop)) {
PyErr_Format(PyExc_AttributeError,
"bpy_struct: attribute \"%.200s\" from \"%.200s\" is read-only",
@@ -4497,22 +4466,21 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
name);
return -1;
}
- else {
- PointerRNA newptr;
- ListBase newlb;
- short newtype;
- int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
+ PointerRNA newptr;
+ ListBase newlb;
+ short newtype;
- if (done == 1) {
- PyErr_Format(
- PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
- BLI_freelistN(&newlb);
- return -1;
- }
+ int done = CTX_data_get(C, name, &newptr, &newlb, &newtype);
+ if (done == 1) {
+ PyErr_Format(
+ PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name);
BLI_freelistN(&newlb);
+ return -1;
}
+
+ BLI_freelistN(&newlb);
}
/* pyrna_py_to_prop sets its own exceptions */
@@ -4523,9 +4491,8 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject
}
return pyrna_py_to_prop(&self->ptr, prop, NULL, value, "bpy_struct: item.attr = val:");
}
- else {
- return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
- }
+
+ return PyObject_GenericSetAttr((PyObject *)self, pyname, value);
}
static PyObject *pyrna_prop_dir(BPy_PropertyRNA *self)
@@ -4563,7 +4530,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
PyErr_SetString(PyExc_AttributeError, "bpy_prop_collection: __getattr__ must be a string");
return NULL;
}
- else if (name[0] != '_') {
+ if (name[0] != '_') {
PyObject *ret;
PropertyRNA *prop;
FunctionRNA *func;
@@ -4575,7 +4542,7 @@ static PyObject *pyrna_prop_collection_getattro(BPy_PropertyRNA *self, PyObject
return ret;
}
- else if ((func = RNA_struct_find_function(r_ptr.type, name))) {
+ if ((func = RNA_struct_find_function(r_ptr.type, name))) {
PyObject *self_collection = pyrna_struct_CreatePyObject(&r_ptr);
ret = pyrna_func_to_py(&((BPy_DummyPointerRNA *)self_collection)->ptr, func);
Py_DECREF(self_collection);
@@ -4639,11 +4606,11 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam
PyErr_SetString(PyExc_AttributeError, "bpy_prop: __setattr__ must be a string");
return -1;
}
- else if (value == NULL) {
+ if (value == NULL) {
PyErr_SetString(PyExc_AttributeError, "bpy_prop: del not supported");
return -1;
}
- else if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
+ if (RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) {
if ((prop = RNA_struct_find_property(&r_ptr, name))) {
/* pyrna_py_to_prop sets its own exceptions. */
return pyrna_py_to_prop(&r_ptr, prop, NULL, value, "BPy_PropertyRNA - Attribute (setattr):");
@@ -4673,9 +4640,8 @@ static PyObject *pyrna_prop_collection_idprop_add(BPy_PropertyRNA *self)
"bpy_prop_collection.add(): not supported for this collection");
return NULL;
}
- else {
- return pyrna_struct_CreatePyObject(&r_ptr);
- }
+
+ return pyrna_struct_CreatePyObject(&r_ptr);
}
static PyObject *pyrna_prop_collection_idprop_remove(BPy_PropertyRNA *self, PyObject *value)
@@ -5798,7 +5764,7 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *
Py_INCREF(base);
return (PyObject *)base;
}
- else if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
+ if (PyType_IsSubtype(Py_TYPE(base), &pyrna_struct_Type)) {
/* this almost never runs, only when using user defined subclasses of built-in object.
* this isn't common since it's NOT related to registerable subclasses. eg:
*
@@ -5826,10 +5792,9 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject *
type->tp_name);
return NULL;
}
- else {
- PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument");
- return NULL;
- }
+
+ PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument");
+ return NULL;
}
/* only needed for subtyping, so a new class gets a valid BPy_StructRNA
@@ -5845,18 +5810,17 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN
if (type == Py_TYPE(base)) {
return Py_INCREF_RET((PyObject *)base);
}
- else if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
+ if (PyType_IsSubtype(type, &pyrna_prop_Type)) {
BPy_PropertyRNA *ret = (BPy_PropertyRNA *)type->tp_alloc(type, 0);
ret->ptr = base->ptr;
ret->prop = base->prop;
return (PyObject *)ret;
}
- else {
- PyErr_Format(PyExc_TypeError,
- "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop",
- type->tp_name);
- return NULL;
- }
+
+ PyErr_Format(PyExc_TypeError,
+ "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop",
+ type->tp_name);
+ return NULL;
}
static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *data)
@@ -6192,9 +6156,8 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
err = -1;
break;
}
- else { /* PyDict_GetItemString wont raise an error. */
- continue;
- }
+ /* PyDict_GetItemString wont raise an error. */
+ continue;
}
#ifdef DEBUG_STRING_FREE
@@ -7131,25 +7094,24 @@ static PyObject *pyrna_prop_collection_iter_next(BPy_PropertyCollectionIterRNA *
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
- else {
- BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr);
+
+ BPy_StructRNA *pyrna = (BPy_StructRNA *)pyrna_struct_CreatePyObject(&self->iter.ptr);
# ifdef USE_PYRNA_STRUCT_REFERENCE
- if (pyrna) { /* Unlikely, but may fail. */
- if ((PyObject *)pyrna != Py_None) {
- /* hold a reference to the iterator since it may have
- * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */
- /* TODO, we could have an api call to know if this is
- * needed since most collections don't */
- pyrna_struct_reference_set(pyrna, (PyObject *)self);
- }
+ if (pyrna) { /* Unlikely, but may fail. */
+ if ((PyObject *)pyrna != Py_None) {
+ /* hold a reference to the iterator since it may have
+ * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's */
+ /* TODO, we could have an api call to know if this is
+ * needed since most collections don't */
+ pyrna_struct_reference_set(pyrna, (PyObject *)self);
}
+ }
# endif /* !USE_PYRNA_STRUCT_REFERENCE */
- RNA_property_collection_next(&self->iter);
+ RNA_property_collection_next(&self->iter);
- return (PyObject *)pyrna;
- }
+ return (PyObject *)pyrna;
}
static void pyrna_prop_collection_iter_dealloc(BPy_PropertyCollectionIterRNA *self)
@@ -7413,9 +7375,8 @@ static StructRNA *srna_from_ptr(PointerRNA *ptr)
if (ptr->type == &RNA_Struct) {
return ptr->data;
}
- else {
- return ptr->type;
- }
+
+ return ptr->type;
}
/* Always returns a new ref, be sure to decref when done. */
@@ -7445,15 +7406,14 @@ PyObject *pyrna_struct_CreatePyObject(PointerRNA *ptr)
Py_INCREF(pyrna);
return (PyObject *)pyrna;
}
- else {
- /* Existing users will need to use 'type_recast' method. */
- Py_DECREF(pyrna);
- *instance = NULL;
- /* Continue as if no instance was made. */
+
+ /* Existing users will need to use 'type_recast' method. */
+ Py_DECREF(pyrna);
+ *instance = NULL;
+ /* Continue as if no instance was made. */
#if 0 /* No need to assign, will be written to next... */
pyrna = NULL;
#endif
- }
}
{
@@ -7560,9 +7520,8 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
RNA_id_pointer_create(id, &ptr);
return pyrna_struct_CreatePyObject(&ptr);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
@@ -7571,10 +7530,9 @@ bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
*id = ((BPy_StructRNA *)obj)->ptr.owner_id;
return true;
}
- else {
- *id = NULL;
- return false;
- }
+
+ *id = NULL;
+ return false;
}
bool pyrna_id_CheckPyObject(PyObject *obj)
@@ -7869,30 +7827,29 @@ StructRNA *srna_from_self(PyObject *self, const char *error_prefix)
if (self == NULL) {
return NULL;
}
- else if (PyCapsule_CheckExact(self)) {
+ if (PyCapsule_CheckExact(self)) {
return PyCapsule_GetPointer(self, NULL);
}
- else if (PyType_Check(self) == 0) {
+ if (PyType_Check(self) == 0) {
return NULL;
}
- else {
- /* These cases above not errors, they just mean the type was not compatible
- * After this any errors will be raised in the script */
- PyObject *error_type, *error_value, *error_traceback;
- StructRNA *srna;
+ /* These cases above not errors, they just mean the type was not compatible
+ * After this any errors will be raised in the script */
- PyErr_Fetch(&error_type, &error_value, &error_traceback);
- PyErr_Clear();
+ PyObject *error_type, *error_value, *error_traceback;
+ StructRNA *srna;
- srna = pyrna_struct_as_srna(self, false, error_prefix);
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ PyErr_Clear();
- if (!PyErr_Occurred()) {
- PyErr_Restore(error_type, error_value, error_traceback);
- }
+ srna = pyrna_struct_as_srna(self, false, error_prefix);
- return srna;
+ if (!PyErr_Occurred()) {
+ PyErr_Restore(error_type, error_value, error_traceback);
}
+
+ return srna;
}
static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item)
diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c
index 8aba2ae8598..ae19f89c348 100644
--- a/source/blender/python/intern/bpy_rna_anim.c
+++ b/source/blender/python/intern/bpy_rna_anim.c
@@ -181,24 +181,24 @@ static int pyrna_struct_anim_args_parse_no_resolve(PointerRNA *ptr,
*r_path_full = path;
return 0;
}
- else {
- char *path_prefix = RNA_path_from_ID_to_struct(ptr);
- if (path_prefix == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s could not make path for type %s",
- error_prefix,
- RNA_struct_identifier(ptr->type));
- return -1;
- }
- if (*path == '[') {
- *r_path_full = BLI_string_joinN(path_prefix, path);
- }
- else {
- *r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path);
- }
- MEM_freeN(path_prefix);
+ char *path_prefix = RNA_path_from_ID_to_struct(ptr);
+ if (path_prefix == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s could not make path for type %s",
+ error_prefix,
+ RNA_struct_identifier(ptr->type));
+ return -1;
+ }
+
+ if (*path == '[') {
+ *r_path_full = BLI_string_joinN(path_prefix, path);
}
+ else {
+ *r_path_full = BLI_string_join_by_sep_charN('.', path_prefix, path);
+ }
+ MEM_freeN(path_prefix);
+
return 0;
}
@@ -383,33 +383,32 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb
return PyBool_FromLong(result);
}
- else {
- ID *id = self->ptr.owner_id;
- ReportList reports;
- bool result;
-
- BKE_reports_init(&reports, RPT_STORE);
-
- BLI_assert(BKE_id_is_in_global_main(id));
- result = (insert_keyframe(G_MAIN,
- &reports,
- id,
- NULL,
- group_name,
- path_full,
- index,
- &anim_eval_context,
- keytype,
- NULL,
- options) != 0);
- MEM_freeN((void *)path_full);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
- return NULL;
- }
-
- return PyBool_FromLong(result);
+ ID *id = self->ptr.owner_id;
+ ReportList reports;
+ bool result;
+
+ BKE_reports_init(&reports, RPT_STORE);
+
+ BLI_assert(BKE_id_is_in_global_main(id));
+ result = (insert_keyframe(G_MAIN,
+ &reports,
+ id,
+ NULL,
+ group_name,
+ path_full,
+ index,
+ &anim_eval_context,
+ keytype,
+ NULL,
+ options) != 0);
+ MEM_freeN((void *)path_full);
+
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
+ return NULL;
}
+
+ return PyBool_FromLong(result);
}
char pyrna_struct_keyframe_delete_doc[] =
@@ -453,7 +452,7 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
NULL) == -1) {
return NULL;
}
- else if (self->ptr.type == &RNA_NlaStrip) {
+ if (self->ptr.type == &RNA_NlaStrip) {
/* Handle special properties for NLA Strips, whose F-Curves are stored on the
* strips themselves. These are stored separately or else the properties will
* not have any effect.
@@ -518,22 +517,21 @@ PyObject *pyrna_struct_keyframe_delete(BPy_StructRNA *self, PyObject *args, PyOb
return PyBool_FromLong(result);
}
- else {
- bool result;
- ReportList reports;
- BKE_reports_init(&reports, RPT_STORE);
+ bool result;
+ ReportList reports;
- result = (delete_keyframe(
- G.main, &reports, self->ptr.owner_id, NULL, path_full, index, cfra) != 0);
- MEM_freeN((void *)path_full);
+ BKE_reports_init(&reports, RPT_STORE);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
- return NULL;
- }
+ result = (delete_keyframe(G.main, &reports, self->ptr.owner_id, NULL, path_full, index, cfra) !=
+ 0);
+ MEM_freeN((void *)path_full);
- return PyBool_FromLong(result);
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
+ return NULL;
}
+
+ return PyBool_FromLong(result);
}
char pyrna_struct_driver_add_doc[] =
@@ -563,60 +561,59 @@ PyObject *pyrna_struct_driver_add(BPy_StructRNA *self, PyObject *args)
&self->ptr, "bpy_struct.driver_add():", path, &path_full, &index) == -1) {
return NULL;
}
- else {
- PyObject *ret = NULL;
- ReportList reports;
- int result;
- BKE_reports_init(&reports, RPT_STORE);
+ PyObject *ret = NULL;
+ ReportList reports;
+ int result;
- result = ANIM_add_driver(&reports,
- (ID *)self->ptr.owner_id,
- path_full,
- index,
- CREATEDRIVER_WITH_FMODIFIER,
- DRIVER_TYPE_PYTHON);
+ BKE_reports_init(&reports, RPT_STORE);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
- return NULL;
- }
+ result = ANIM_add_driver(&reports,
+ (ID *)self->ptr.owner_id,
+ path_full,
+ index,
+ CREATEDRIVER_WITH_FMODIFIER,
+ DRIVER_TYPE_PYTHON);
- if (result) {
- ID *id = self->ptr.owner_id;
- AnimData *adt = BKE_animdata_from_id(id);
- FCurve *fcu;
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
+ return NULL;
+ }
- PointerRNA tptr;
+ if (result) {
+ ID *id = self->ptr.owner_id;
+ AnimData *adt = BKE_animdata_from_id(id);
+ FCurve *fcu;
- if (index == -1) { /* all, use a list */
- int i = 0;
- ret = PyList_New(0);
- while ((fcu = BKE_fcurve_find(&adt->drivers, path_full, i++))) {
- RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
- PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr));
- }
- }
- else {
- fcu = BKE_fcurve_find(&adt->drivers, path_full, index);
+ PointerRNA tptr;
+
+ if (index == -1) { /* all, use a list */
+ int i = 0;
+ ret = PyList_New(0);
+ while ((fcu = BKE_fcurve_find(&adt->drivers, path_full, i++))) {
RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
- ret = pyrna_struct_CreatePyObject(&tptr);
+ PyList_APPEND(ret, pyrna_struct_CreatePyObject(&tptr));
}
-
- bContext *context = BPy_GetContext();
- WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
- DEG_relations_tag_update(CTX_data_main(context));
}
else {
- /* XXX, should be handled by reports, */
- PyErr_SetString(PyExc_TypeError,
- "bpy_struct.driver_add(): failed because of an internal error");
- return NULL;
+ fcu = BKE_fcurve_find(&adt->drivers, path_full, index);
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &tptr);
+ ret = pyrna_struct_CreatePyObject(&tptr);
}
- MEM_freeN((void *)path_full);
-
- return ret;
+ bContext *context = BPy_GetContext();
+ WM_event_add_notifier(BPy_GetContext(), NC_ANIMATION | ND_FCURVES_ORDER, NULL);
+ DEG_relations_tag_update(CTX_data_main(context));
}
+ else {
+ /* XXX, should be handled by reports, */
+ PyErr_SetString(PyExc_TypeError,
+ "bpy_struct.driver_add(): failed because of an internal error");
+ return NULL;
+ }
+
+ MEM_freeN((void *)path_full);
+
+ return ret;
}
char pyrna_struct_driver_remove_doc[] =
@@ -646,26 +643,25 @@ PyObject *pyrna_struct_driver_remove(BPy_StructRNA *self, PyObject *args)
&self->ptr, "bpy_struct.driver_remove():", path, &path_full, &index) == -1) {
return NULL;
}
- else {
- short result;
- ReportList reports;
- BKE_reports_init(&reports, RPT_STORE);
+ short result;
+ ReportList reports;
- result = ANIM_remove_driver(&reports, (ID *)self->ptr.owner_id, path_full, index, 0);
+ BKE_reports_init(&reports, RPT_STORE);
- if (path != path_full) {
- MEM_freeN((void *)path_full);
- }
+ result = ANIM_remove_driver(&reports, (ID *)self->ptr.owner_id, path_full, index, 0);
- if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
- return NULL;
- }
-
- bContext *context = BPy_GetContext();
- WM_event_add_notifier(context, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
- DEG_relations_tag_update(CTX_data_main(context));
+ if (path != path_full) {
+ MEM_freeN((void *)path_full);
+ }
- return PyBool_FromLong(result);
+ if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) {
+ return NULL;
}
+
+ bContext *context = BPy_GetContext();
+ WM_event_add_notifier(context, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
+ DEG_relations_tag_update(CTX_data_main(context));
+
+ return PyBool_FromLong(result);
}
diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c
index 1e5b53b819e..66e07d556a6 100644
--- a/source/blender/python/intern/bpy_rna_array.c
+++ b/source/blender/python/intern/bpy_rna_array.c
@@ -180,7 +180,7 @@ static int validate_array_type(PyObject *seq,
Py_TYPE(seq)->tp_name);
return -1;
}
- else if ((seq_size != dimsize[dim]) && (is_dynamic == false)) {
+ if ((seq_size != dimsize[dim]) && (is_dynamic == false)) {
PyErr_Format(PyExc_ValueError,
"%s sequences of dimension %d should contain %d items, not %d",
error_prefix,
@@ -201,7 +201,7 @@ static int validate_array_type(PyObject *seq,
i);
return -1;
}
- else if (!check_item_type(item)) {
+ if (!check_item_type(item)) {
Py_DECREF(item);
#if 0
@@ -279,7 +279,7 @@ static int validate_array_length(PyObject *rvalue,
RNA_property_identifier(prop));
return -1;
}
- else if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
+ if ((RNA_property_flag(prop) & PROP_DYNAMIC) && lvalue_dim == 0) {
if (RNA_property_array_length(ptr, prop) != tot) {
#if 0
/* length is flexible */
@@ -382,7 +382,7 @@ static int validate_array(PyObject *rvalue,
RNA_property_identifier(prop));
return -1;
}
- else if (totdim != 2) {
+ if (totdim != 2) {
PyErr_Format(PyExc_ValueError,
"%s %.200s.%.200s, matrix assign array with %d dimensions",
error_prefix,
@@ -391,7 +391,7 @@ static int validate_array(PyObject *rvalue,
totdim);
return -1;
}
- else if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) {
+ if (pymat->num_col != dimsize[0] || pymat->num_row != dimsize[1]) {
PyErr_Format(PyExc_ValueError,
"%s %.200s.%.200s, matrix assign dimension size mismatch, "
"is %dx%d, expected be %dx%d",
@@ -404,10 +404,9 @@ static int validate_array(PyObject *rvalue,
dimsize[1]);
return -1;
}
- else {
- *r_totitem = dimsize[0] * dimsize[1];
- return 0;
- }
+
+ *r_totitem = dimsize[0] * dimsize[1];
+ return 0;
}
}
#endif /* USE_MATHUTILS */
@@ -1017,31 +1016,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
PyErr_Clear();
return 0;
}
- else {
- float tmp[32];
- float *tmp_arr;
- if (len * sizeof(float) > sizeof(tmp)) {
- tmp_arr = PyMem_MALLOC(len * sizeof(float));
- }
- else {
- tmp_arr = tmp;
- }
+ float tmp[32];
+ float *tmp_arr;
- RNA_property_float_get_array(ptr, prop, tmp_arr);
+ if (len * sizeof(float) > sizeof(tmp)) {
+ tmp_arr = PyMem_MALLOC(len * sizeof(float));
+ }
+ else {
+ tmp_arr = tmp;
+ }
- for (i = 0; i < len; i++) {
- if (tmp_arr[i] == value_f) {
- break;
- }
- }
+ RNA_property_float_get_array(ptr, prop, tmp_arr);
- if (tmp_arr != tmp) {
- PyMem_FREE(tmp_arr);
+ for (i = 0; i < len; i++) {
+ if (tmp_arr[i] == value_f) {
+ break;
}
+ }
- return i < len ? 1 : 0;
+ if (tmp_arr != tmp) {
+ PyMem_FREE(tmp_arr);
}
+
+ return i < len ? 1 : 0;
+
break;
}
case PROP_INT: {
@@ -1050,31 +1049,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
PyErr_Clear();
return 0;
}
- else {
- int tmp[32];
- int *tmp_arr;
- if (len * sizeof(int) > sizeof(tmp)) {
- tmp_arr = PyMem_MALLOC(len * sizeof(int));
- }
- else {
- tmp_arr = tmp;
- }
+ int tmp[32];
+ int *tmp_arr;
- RNA_property_int_get_array(ptr, prop, tmp_arr);
+ if (len * sizeof(int) > sizeof(tmp)) {
+ tmp_arr = PyMem_MALLOC(len * sizeof(int));
+ }
+ else {
+ tmp_arr = tmp;
+ }
- for (i = 0; i < len; i++) {
- if (tmp_arr[i] == value_i) {
- break;
- }
- }
+ RNA_property_int_get_array(ptr, prop, tmp_arr);
- if (tmp_arr != tmp) {
- PyMem_FREE(tmp_arr);
+ for (i = 0; i < len; i++) {
+ if (tmp_arr[i] == value_i) {
+ break;
}
+ }
- return i < len ? 1 : 0;
+ if (tmp_arr != tmp) {
+ PyMem_FREE(tmp_arr);
}
+
+ return i < len ? 1 : 0;
+
break;
}
case PROP_BOOLEAN: {
@@ -1083,31 +1082,31 @@ int pyrna_array_contains_py(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
PyErr_Clear();
return 0;
}
- else {
- bool tmp[32];
- bool *tmp_arr;
- if (len * sizeof(bool) > sizeof(tmp)) {
- tmp_arr = PyMem_MALLOC(len * sizeof(bool));
- }
- else {
- tmp_arr = tmp;
- }
+ bool tmp[32];
+ bool *tmp_arr;
- RNA_property_boolean_get_array(ptr, prop, tmp_arr);
+ if (len * sizeof(bool) > sizeof(tmp)) {
+ tmp_arr = PyMem_MALLOC(len * sizeof(bool));
+ }
+ else {
+ tmp_arr = tmp;
+ }
- for (i = 0; i < len; i++) {
- if (tmp_arr[i] == value_i) {
- break;
- }
- }
+ RNA_property_boolean_get_array(ptr, prop, tmp_arr);
- if (tmp_arr != tmp) {
- PyMem_FREE(tmp_arr);
+ for (i = 0; i < len; i++) {
+ if (tmp_arr[i] == value_i) {
+ break;
}
+ }
- return i < len ? 1 : 0;
+ if (tmp_arr != tmp) {
+ PyMem_FREE(tmp_arr);
}
+
+ return i < len ? 1 : 0;
+
break;
}
}
diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c
index f9bcb8943f4..976b8a65ac7 100644
--- a/source/blender/python/intern/bpy_rna_callback.c
+++ b/source/blender/python/intern/bpy_rna_callback.c
@@ -317,10 +317,10 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
error_prefix) == -1) {
return NULL;
}
- else if (params.region_type_str && pyrna_enum_value_from_id(rna_enum_region_type_items,
- params.region_type_str,
- &params.region_type,
- error_prefix) == -1) {
+ if (params.region_type_str && pyrna_enum_value_from_id(rna_enum_region_type_items,
+ params.region_type_str,
+ &params.region_type,
+ error_prefix) == -1) {
return NULL;
}
@@ -352,29 +352,26 @@ PyObject *pyrna_callback_classmethod_add(PyObject *UNUSED(self), PyObject *args)
region_draw_mode_items, params.event_str, &params.event, error_prefix) == -1) {
return NULL;
}
- else if (pyrna_enum_value_from_id(rna_enum_region_type_items,
- params.region_type_str,
- &params.region_type,
- error_prefix) == -1) {
+ if (pyrna_enum_value_from_id(rna_enum_region_type_items,
+ params.region_type_str,
+ &params.region_type,
+ error_prefix) == -1) {
return NULL;
}
- else {
- const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
- if (spaceid == SPACE_EMPTY) {
- PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
- return NULL;
- }
- else {
- SpaceType *st = BKE_spacetype_from_id(spaceid);
- ARegionType *art = BKE_regiontype_from_id(st, params.region_type);
- if (art == NULL) {
- PyErr_Format(
- PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str);
- return NULL;
- }
- handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, params.event);
- }
+
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == SPACE_EMPTY) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
}
+
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, params.region_type);
+ if (art == NULL) {
+ PyErr_Format(PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str);
+ return NULL;
+ }
+ handle = ED_region_draw_cb_activate(art, cb_region_draw, (void *)args, params.event);
}
else {
PyErr_SetString(PyExc_TypeError, "callback_add(): type does not support callbacks");
@@ -448,24 +445,21 @@ PyObject *pyrna_callback_classmethod_remove(PyObject *UNUSED(self), PyObject *ar
error_prefix) == -1) {
return NULL;
}
- else {
- const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
- if (spaceid == SPACE_EMPTY) {
- PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
- return NULL;
- }
- else {
- SpaceType *st = BKE_spacetype_from_id(spaceid);
- ARegionType *art = BKE_regiontype_from_id(st, params.region_type);
- if (art == NULL) {
- PyErr_Format(
- PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str);
- return NULL;
- }
- ED_region_draw_cb_exit(art, handle);
- capsule_clear = true;
- }
+
+ const eSpace_Type spaceid = rna_Space_refine_reverse(srna);
+ if (spaceid == SPACE_EMPTY) {
+ PyErr_Format(PyExc_TypeError, "unknown space type '%.200s'", RNA_struct_identifier(srna));
+ return NULL;
}
+
+ SpaceType *st = BKE_spacetype_from_id(spaceid);
+ ARegionType *art = BKE_regiontype_from_id(st, params.region_type);
+ if (art == NULL) {
+ PyErr_Format(PyExc_TypeError, "region type '%.200s' not in space", params.region_type_str);
+ return NULL;
+ }
+ ED_region_draw_cb_exit(art, handle);
+ capsule_clear = true;
}
else {
PyErr_SetString(PyExc_TypeError, "callback_remove(): type does not support callbacks");
diff --git a/source/blender/python/intern/bpy_rna_gizmo.c b/source/blender/python/intern/bpy_rna_gizmo.c
index aff81c68358..4ef718ef023 100644
--- a/source/blender/python/intern/bpy_rna_gizmo.c
+++ b/source/blender/python/intern/bpy_rna_gizmo.c
@@ -367,10 +367,10 @@ static PyObject *bpy_gizmo_target_get_value(PyObject *UNUSED(self), PyObject *ar
WM_gizmo_target_property_float_get_array(gz, gz_prop, value);
return PyC_Tuple_PackArray_F32(value, array_len);
}
- else {
- float value = WM_gizmo_target_property_float_get(gz, gz_prop);
- return PyFloat_FromDouble(value);
- }
+
+ float value = WM_gizmo_target_property_float_get(gz, gz_prop);
+ return PyFloat_FromDouble(value);
+
break;
}
default: {
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 5764db4e70c..308d2ef9618 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -249,42 +249,41 @@ int mathutils_array_parse_alloc(float **array,
memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
return size;
}
- else
-#endif
- {
- PyObject *value_fast = NULL;
- // *array = NULL;
- int ret;
- /* non list/tuple cases */
- if (!(value_fast = PySequence_Fast(value, error_prefix))) {
- /* PySequence_Fast sets the error */
- return -1;
- }
+#endif
- size = PySequence_Fast_GET_SIZE(value_fast);
+ PyObject *value_fast = NULL;
+ // *array = NULL;
+ int ret;
- if (size < array_min) {
- Py_DECREF(value_fast);
- PyErr_Format(PyExc_ValueError,
- "%.200s: sequence size is %d, expected > %d",
- error_prefix,
- size,
- array_min);
- return -1;
- }
+ /* non list/tuple cases */
+ if (!(value_fast = PySequence_Fast(value, error_prefix))) {
+ /* PySequence_Fast sets the error */
+ return -1;
+ }
- *array = PyMem_Malloc(size * sizeof(float));
+ size = PySequence_Fast_GET_SIZE(value_fast);
- ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
+ if (size < array_min) {
Py_DECREF(value_fast);
+ PyErr_Format(PyExc_ValueError,
+ "%.200s: sequence size is %d, expected > %d",
+ error_prefix,
+ size,
+ array_min);
+ return -1;
+ }
- if (ret == -1) {
- PyMem_Free(*array);
- }
+ *array = PyMem_Malloc(size * sizeof(float));
+
+ ret = mathutils_array_parse_fast(*array, size, value_fast, error_prefix);
+ Py_DECREF(value_fast);
- return ret;
+ if (ret == -1) {
+ PyMem_Free(*array);
}
+
+ return ret;
}
/* parse an array of vectors */
@@ -482,45 +481,41 @@ int mathutils_any_to_rotmat(float rmat[3][3], PyObject *value, const char *error
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- else {
- eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
- return 0;
- }
+
+ eulO_to_mat3(rmat, ((EulerObject *)value)->eul, ((EulerObject *)value)->order);
+ return 0;
}
- else if (QuaternionObject_Check(value)) {
+ if (QuaternionObject_Check(value)) {
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- else {
- float tquat[4];
- normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
- quat_to_mat3(rmat, tquat);
- return 0;
- }
+
+ float tquat[4];
+ normalize_qt_qt(tquat, ((QuaternionObject *)value)->quat);
+ quat_to_mat3(rmat, tquat);
+ return 0;
}
- else if (MatrixObject_Check(value)) {
+ if (MatrixObject_Check(value)) {
if (BaseMath_ReadCallback((BaseMathObject *)value) == -1) {
return -1;
}
- else if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
+ if (((MatrixObject *)value)->num_row < 3 || ((MatrixObject *)value)->num_col < 3) {
PyErr_Format(
PyExc_ValueError, "%.200s: matrix must have minimum 3x3 dimensions", error_prefix);
return -1;
}
- else {
- matrix_as_3x3(rmat, (MatrixObject *)value);
- normalize_m3(rmat);
- return 0;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "%.200s: expected a Euler, Quaternion or Matrix type, "
- "found %.200s",
- error_prefix,
- Py_TYPE(value)->tp_name);
- return -1;
+
+ matrix_as_3x3(rmat, (MatrixObject *)value);
+ normalize_m3(rmat);
+ return 0;
}
+
+ PyErr_Format(PyExc_TypeError,
+ "%.200s: expected a Euler, Quaternion or Matrix type, "
+ "found %.200s",
+ error_prefix,
+ Py_TYPE(value)->tp_name);
+ return -1;
}
/* ----------------------------------MATRIX FUNCTIONS-------------------- */
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index 08dede8ff78..6bffff467cd 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -347,7 +347,7 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item)
}
return Color_item(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -357,19 +357,17 @@ static PyObject *Color_subscript(ColorObject *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Color_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *value)
@@ -384,7 +382,7 @@ static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *valu
}
return Color_ass_item(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, COLOR_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -394,16 +392,14 @@ static int Color_ass_subscript(ColorObject *self, PyObject *item, PyObject *valu
if (step == 1) {
return Color_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with color");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "color indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
/* -----------------PROTCOL DECLARATIONS-------------------------- */
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index 7ece587e38f..ebc71706bef 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -558,7 +558,7 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
}
return Euler_item(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -568,19 +568,17 @@ static PyObject *Euler_subscript(EulerObject *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Euler_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with eulers");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with eulers");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *value)
@@ -595,7 +593,7 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu
}
return Euler_ass_item(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, EULER_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -605,16 +603,14 @@ static int Euler_ass_subscript(EulerObject *self, PyObject *item, PyObject *valu
if (step == 1) {
return Euler_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with euler");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with euler");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "euler indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
/* -----------------PROTCOL DECLARATIONS-------------------------- */
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index 3e30c81c8c6..236bb1de29d 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -54,9 +54,8 @@ static int matrix_row_vector_check(MatrixObject *mat, VectorObject *vec, int row
"owner matrix has been resized since this row vector was created");
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col)
@@ -67,9 +66,8 @@ static int matrix_col_vector_check(MatrixObject *mat, VectorObject *vec, int col
"owner matrix has been resized since this column vector was created");
return 0;
}
- else {
- return 1;
- }
+
+ return 1;
}
/* ----------------------------------------------------------------------------
@@ -380,9 +378,8 @@ static PyObject *Matrix_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (Matrix_ass_slice((MatrixObject *)matrix, 0, INT_MAX, arg) == 0) {
return matrix;
}
- else { /* matrix ok, slice assignment not */
- Py_DECREF(matrix);
- }
+ /* matrix ok, slice assignment not */
+ Py_DECREF(matrix);
}
}
break;
@@ -406,15 +403,13 @@ static PyObject *matrix__apply_to_copy(PyObject *(*matrix_func)(MatrixObject *),
Py_DECREF(ret_dummy);
return ret;
}
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
- }
- else {
- /* copy may fail if the read callback errors out */
+ /* error */
+ Py_DECREF(ret);
return NULL;
}
+
+ /* copy may fail if the read callback errors out */
+ return NULL;
}
/* when a matrix is 4x4 size but initialized as a 3x3, re-assign values for 4x4 */
@@ -512,10 +507,9 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args)
"or a string in 'X', 'Y', 'Z'");
return NULL;
}
- else {
- /* use the string */
- vec = NULL;
- }
+
+ /* use the string */
+ vec = NULL;
}
angle = angle_wrap_rad(angle);
@@ -1023,7 +1017,7 @@ static float matrix_determinant_internal(const MatrixObject *self)
MATRIX_ITEM(self, 1, 0),
MATRIX_ITEM(self, 1, 1));
}
- else if (self->num_col == 3) {
+ if (self->num_col == 3) {
return determinant_m3(MATRIX_ITEM(self, 0, 0),
MATRIX_ITEM(self, 0, 1),
MATRIX_ITEM(self, 0, 2),
@@ -1034,9 +1028,8 @@ static float matrix_determinant_internal(const MatrixObject *self)
MATRIX_ITEM(self, 2, 1),
MATRIX_ITEM(self, 2, 2));
}
- else {
- return determinant_m4((float(*)[4])self->matrix);
- }
+
+ return determinant_m4((float(*)[4])self->matrix);
}
static void adjoint_matrix_n(float *mat_dst, const float *mat_src, const ushort dim)
@@ -1094,9 +1087,8 @@ static bool matrix_invert_internal(const MatrixObject *self, float *r_mat)
matrix_invert_with_det_n_internal(r_mat, self->matrix, det, self->num_col);
return true;
}
- else {
- return false;
- }
+
+ return false;
}
/**
@@ -1475,9 +1467,8 @@ static bool matrix_invert_is_compat(const MatrixObject *self)
"only square matrices are supported");
return false;
}
- else {
- return true;
- }
+
+ return true;
}
static bool matrix_invert_args_check(const MatrixObject *self, PyObject *args, bool check_type)
@@ -1605,10 +1596,9 @@ static PyObject *Matrix_inverted(MatrixObject *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- matrix_invert_raise_degenerate();
- return NULL;
- }
+
+ matrix_invert_raise_degenerate();
+ return NULL;
}
return Matrix_copy_notest(self, mat);
@@ -2386,48 +2376,47 @@ static int Matrix_ass_slice(MatrixObject *self, int begin, int end, PyObject *va
/* PySequence_Fast sets the error */
return -1;
}
- else {
- PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
- const int size = end - begin;
- int row, col;
- float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
- float vec[4];
- if (PySequence_Fast_GET_SIZE(value_fast) != size) {
- Py_DECREF(value_fast);
- PyErr_SetString(PyExc_ValueError,
- "matrix[begin:end] = []: "
- "size mismatch in slice assignment");
- return -1;
- }
+ PyObject **value_fast_items = PySequence_Fast_ITEMS(value_fast);
+ const int size = end - begin;
+ int row, col;
+ float mat[MATRIX_MAX_DIM * MATRIX_MAX_DIM];
+ float vec[4];
+
+ if (PySequence_Fast_GET_SIZE(value_fast) != size) {
+ Py_DECREF(value_fast);
+ PyErr_SetString(PyExc_ValueError,
+ "matrix[begin:end] = []: "
+ "size mismatch in slice assignment");
+ return -1;
+ }
- memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float));
+ memcpy(mat, self->matrix, self->num_col * self->num_row * sizeof(float));
- /* parse sub items */
- for (row = begin; row < end; row++) {
- /* parse each sub sequence */
- PyObject *item = value_fast_items[row - begin];
+ /* parse sub items */
+ for (row = begin; row < end; row++) {
+ /* parse each sub sequence */
+ PyObject *item = value_fast_items[row - begin];
- if (mathutils_array_parse(
- vec, self->num_col, self->num_col, item, "matrix[begin:end] = value assignment") ==
- -1) {
- Py_DECREF(value_fast);
- return -1;
- }
+ if (mathutils_array_parse(
+ vec, self->num_col, self->num_col, 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->num_col; col++) {
+ mat[col * self->num_row + row] = vec[col];
}
+ }
- Py_DECREF(value_fast);
+ Py_DECREF(value_fast);
- /*parsed well - now set in matrix*/
- memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float));
+ /*parsed well - now set in matrix*/
+ memcpy(self->matrix, mat, self->num_col * self->num_row * sizeof(float));
- (void)BaseMath_WriteCallback(self);
- return 0;
- }
+ (void)BaseMath_WriteCallback(self);
+ return 0;
}
/*------------------------NUMERIC PROTOCOLS----------------------
*------------------------obj + obj------------------------------*/
@@ -2540,7 +2529,7 @@ static PyObject *Matrix_mul(PyObject *m1, PyObject *m2)
return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
}
- else if (mat2) {
+ if (mat2) {
/*FLOAT/INT * MATRIX */
if (((scalar = PyFloat_AsDouble(m1)) == -1.0f && PyErr_Occurred()) == 0) {
return matrix_mul_float(mat2, scalar);
@@ -2655,7 +2644,7 @@ static PyObject *Matrix_matmul(PyObject *m1, PyObject *m2)
return Matrix_CreatePyObject(mat, mat2->num_col, mat1->num_row, Py_TYPE(mat1));
}
- else if (mat1) {
+ if (mat1) {
/* MATRIX @ VECTOR */
if (VectorObject_Check(m2)) {
VectorObject *vec2 = (VectorObject *)m2;
@@ -2772,7 +2761,7 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item)
}
return Matrix_item_row(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
@@ -2782,19 +2771,17 @@ static PyObject *Matrix_subscript(MatrixObject *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Matrix_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *value)
@@ -2809,7 +2796,7 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va
}
return Matrix_ass_item_row(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->num_row, &start, &stop, &step, &slicelength) < 0) {
@@ -2819,16 +2806,14 @@ static int Matrix_ass_subscript(MatrixObject *self, PyObject *item, PyObject *va
if (step == 1) {
return Matrix_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrices");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
static PyMappingMethods Matrix_AsMapping = {
@@ -2977,15 +2962,14 @@ static PyObject *Matrix_is_negative_get(MatrixObject *self, void *UNUSED(closure
if (self->num_row == 4 && self->num_col == 4) {
return PyBool_FromLong(is_negative_m4((float(*)[4])self->matrix));
}
- else if (self->num_row == 3 && self->num_col == 3) {
+ if (self->num_row == 3 && self->num_col == 3) {
return PyBool_FromLong(is_negative_m3((float(*)[3])self->matrix));
}
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_negative: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_negative: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
}
PyDoc_STRVAR(Matrix_is_orthogonal_doc,
@@ -3000,15 +2984,14 @@ static PyObject *Matrix_is_orthogonal_get(MatrixObject *self, void *UNUSED(closu
if (self->num_row == 4 && self->num_col == 4) {
return PyBool_FromLong(is_orthonormal_m4((float(*)[4])self->matrix));
}
- else if (self->num_row == 3 && self->num_col == 3) {
+ if (self->num_row == 3 && self->num_col == 3) {
return PyBool_FromLong(is_orthonormal_m3((float(*)[3])self->matrix));
}
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_orthogonal: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_orthogonal: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
}
PyDoc_STRVAR(Matrix_is_orthogonal_axis_vectors_doc,
@@ -3024,15 +3007,14 @@ static PyObject *Matrix_is_orthogonal_axis_vectors_get(MatrixObject *self, void
if (self->num_row == 4 && self->num_col == 4) {
return PyBool_FromLong(is_orthogonal_m4((float(*)[4])self->matrix));
}
- else if (self->num_row == 3 && self->num_col == 3) {
+ if (self->num_row == 3 && self->num_col == 3) {
return PyBool_FromLong(is_orthogonal_m3((float(*)[3])self->matrix));
}
- else {
- PyErr_SetString(PyExc_AttributeError,
- "Matrix.is_orthogonal_axis_vectors: "
- "inappropriate matrix size - expects 3x3 or 4x4 matrix");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_AttributeError,
+ "Matrix.is_orthogonal_axis_vectors: "
+ "inappropriate matrix size - expects 3x3 or 4x4 matrix");
+ return NULL;
}
/*****************************************************************************/
@@ -3478,14 +3460,13 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item
}
return Matrix_item_row(matrix_user, i);
}
- else { /* MAT_ACCESS_ROW */
- if (i < 0) {
- i += matrix_user->num_col;
- }
- return Matrix_item_col(matrix_user, i);
+ /* MAT_ACCESS_ROW */
+ if (i < 0) {
+ i += matrix_user->num_col;
}
+ return Matrix_item_col(matrix_user, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, MatrixAccess_len(self), &start, &stop, &step, &slicelength) <
@@ -3496,19 +3477,17 @@ static PyObject *MatrixAccess_subscript(MatrixAccessObject *self, PyObject *item
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return MatrixAccess_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrix accessors");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with matrix accessors");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item, PyObject *value)
@@ -3527,19 +3506,17 @@ static int MatrixAccess_ass_subscript(MatrixAccessObject *self, PyObject *item,
}
return Matrix_ass_item_row(matrix_user, i, value);
}
- else { /* MAT_ACCESS_ROW */
- if (i < 0) {
- i += matrix_user->num_col;
- }
- return Matrix_ass_item_col(matrix_user, i, value);
+ /* MAT_ACCESS_ROW */
+ if (i < 0) {
+ i += matrix_user->num_col;
}
+ return Matrix_ass_item_col(matrix_user, i, value);
}
/* TODO, slice */
- else {
- PyErr_Format(
- PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
- return -1;
- }
+
+ PyErr_Format(
+ PyExc_TypeError, "matrix indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
static PyObject *MatrixAccess_iter(MatrixAccessObject *self)
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 2b7761b7678..b0e6b330968 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -815,7 +815,7 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item)
}
return Quaternion_item(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -825,20 +825,17 @@ static PyObject *Quaternion_subscript(QuaternionObject *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Quaternion_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternions");
- return NULL;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "quaternion indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternions");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyObject *value)
@@ -853,7 +850,7 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb
}
return Quaternion_ass_item(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, QUAT_SIZE, &start, &stop, &step, &slicelength) < 0) {
@@ -863,17 +860,14 @@ static int Quaternion_ass_subscript(QuaternionObject *self, PyObject *item, PyOb
if (step == 1) {
return Quaternion_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternion");
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "quaternion indices must be integers, not %.200s",
- Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with quaternion");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "quaternion indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
/* ------------------------NUMERIC PROTOCOLS---------------------- */
@@ -967,7 +961,7 @@ static PyObject *Quaternion_mul(PyObject *q1, PyObject *q2)
return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
/* the only case this can happen (for a supported type is "FLOAT * QUAT") */
- else if (quat2) { /* FLOAT * QUAT */
+ if (quat2) { /* FLOAT * QUAT */
if (((scalar = PyFloat_AsDouble(q1)) == -1.0f && PyErr_Occurred()) == 0) {
return quat_mul_float(quat2, scalar);
}
@@ -1049,7 +1043,7 @@ static PyObject *Quaternion_matmul(PyObject *q1, PyObject *q2)
mul_qt_qtqt(quat, quat1->quat, quat2->quat);
return Quaternion_CreatePyObject(quat, Py_TYPE(q1));
}
- else if (quat1) {
+ if (quat1) {
/* QUAT @ VEC */
if (VectorObject_Check(q2)) {
VectorObject *vec2 = (VectorObject *)q2;
@@ -1384,10 +1378,9 @@ static PyObject *quat__apply_to_copy(PyObject *(*quat_func)(QuaternionObject *),
Py_DECREF(ret_dummy);
return ret;
}
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
+ /* error */
+ Py_DECREF(ret);
+ return NULL;
}
/* axis vector suffers from precision errors, use this function to ensure */
diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c
index 4b47440a530..b30aafbf875 100644
--- a/source/blender/python/mathutils/mathutils_Vector.c
+++ b/source/blender/python/mathutils/mathutils_Vector.c
@@ -104,10 +104,9 @@ static PyObject *vec__apply_to_copy(PyObject *(*vec_func)(VectorObject *), Vecto
Py_DECREF(ret_dummy);
return (PyObject *)ret;
}
- else { /* error */
- Py_DECREF(ret);
- return NULL;
- }
+ /* error */
+ Py_DECREF(ret);
+ return NULL;
}
/*-----------------------CLASS-METHODS----------------------------*/
@@ -1004,12 +1003,11 @@ static PyObject *Vector_angle(VectorObject *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.angle(other): "
- "zero length vectors have no valid angle");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.angle(other): "
+ "zero length vectors have no valid angle");
+ return NULL;
}
return PyFloat_FromDouble(saacos(dot / (sqrt(dot_self) * sqrt(dot_other))));
@@ -1059,12 +1057,11 @@ static PyObject *Vector_angle_signed(VectorObject *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.angle_signed(other): "
- "zero length vectors have no valid angle");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.angle_signed(other): "
+ "zero length vectors have no valid angle");
+ return NULL;
}
return PyFloat_FromDouble(angle_signed_v2v2(self->vec, tvec));
@@ -1238,12 +1235,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.slerp(): "
- "zero length vectors unsupported");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "zero length vectors unsupported");
+ return NULL;
}
/* We have sane state, execute slerp */
@@ -1256,12 +1252,11 @@ static PyObject *Vector_slerp(VectorObject *self, PyObject *args)
Py_INCREF(fallback);
return fallback;
}
- else {
- PyErr_SetString(PyExc_ValueError,
- "Vector.slerp(): "
- "opposite vectors unsupported");
- return NULL;
- }
+
+ PyErr_SetString(PyExc_ValueError,
+ "Vector.slerp(): "
+ "opposite vectors unsupported");
+ return NULL;
}
interp_dot_slerp(fac, cosom, w);
@@ -1785,7 +1780,7 @@ static PyObject *Vector_mul(PyObject *v1, PyObject *v2)
/* element-wise product */
return vector_mul_vec(vec1, vec2);
}
- else if (vec1) {
+ if (vec1) {
if (((scalar = PyFloat_AsDouble(v2)) == -1.0f && PyErr_Occurred()) == 0) { /* VEC * FLOAT */
return vector_mul_float(vec1, scalar);
}
@@ -1890,7 +1885,7 @@ static PyObject *Vector_matmul(PyObject *v1, PyObject *v2)
/*dot product*/
return PyFloat_FromDouble(dot_vn_vn(vec1->vec, vec2->vec, vec1->size));
}
- else if (vec1) {
+ if (vec1) {
if (MatrixObject_Check(v2)) {
/* VEC @ MATRIX */
float tvec[MAX_DIMENSIONS];
@@ -2039,9 +2034,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
if (comparison_type == Py_NE) {
Py_RETURN_TRUE;
}
- else {
- Py_RETURN_FALSE;
- }
+
+ Py_RETURN_FALSE;
}
vecA = (VectorObject *)objectA;
vecB = (VectorObject *)objectB;
@@ -2054,9 +2048,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
if (comparison_type == Py_NE) {
Py_RETURN_TRUE;
}
- else {
- Py_RETURN_FALSE;
- }
+
+ Py_RETURN_FALSE;
}
switch (comparison_type) {
@@ -2107,9 +2100,8 @@ static PyObject *Vector_richcmpr(PyObject *objectA, PyObject *objectB, int compa
if (result == 1) {
Py_RETURN_TRUE;
}
- else {
- Py_RETURN_FALSE;
- }
+
+ Py_RETURN_FALSE;
}
static Py_hash_t Vector_hash(VectorObject *self)
@@ -2152,7 +2144,7 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item)
}
return Vector_item(self, i);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
@@ -2162,19 +2154,17 @@ static PyObject *Vector_subscript(VectorObject *self, PyObject *item)
if (slicelength <= 0) {
return PyTuple_New(0);
}
- else if (step == 1) {
+ if (step == 1) {
return Vector_slice(self, start, stop);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
- return NULL;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
return NULL;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return NULL;
}
static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *value)
@@ -2189,7 +2179,7 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va
}
return Vector_ass_item(self, i, value);
}
- else if (PySlice_Check(item)) {
+ if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx(item, self->size, &start, &stop, &step, &slicelength) < 0) {
@@ -2199,16 +2189,14 @@ static int Vector_ass_subscript(VectorObject *self, PyObject *item, PyObject *va
if (step == 1) {
return Vector_ass_slice(self, start, stop, value);
}
- else {
- PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
- return -1;
- }
- }
- else {
- PyErr_Format(
- PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+
+ PyErr_SetString(PyExc_IndexError, "slice steps not supported with vectors");
return -1;
}
+
+ PyErr_Format(
+ PyExc_TypeError, "vector indices must be integers, not %.200s", Py_TYPE(item)->tp_name);
+ return -1;
}
static PyMappingMethods Vector_AsMapping = {
@@ -2523,9 +2511,8 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
if (BaseMath_WriteCallback(self) == -1) {
return -1;
}
- else {
- return 0;
- }
+
+ return 0;
}
#define _SWIZZLE1(a) ((a) | SWIZZLE_VALID_AXIS)
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 5a0dc7d6a5e..80a72696d77 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -914,16 +914,15 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P
return bvhtree_CreatePyObject(
tree, epsilon, coords, coords_len, tris, tris_len, orig_index, orig_normal);
}
- else {
- if (coords) {
- MEM_freeN(coords);
- }
- if (tris) {
- MEM_freeN(tris);
- }
- return NULL;
+ if (coords) {
+ MEM_freeN(coords);
+ }
+ if (tris) {
+ MEM_freeN(tris);
}
+
+ return NULL;
}
#ifndef MATH_STANDALONE
@@ -1053,55 +1052,48 @@ static Mesh *bvh_get_mesh(const char *funcname,
funcname);
return NULL;
}
- else {
- *r_free_mesh = true;
- return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks);
- }
+
+ *r_free_mesh = true;
+ return mesh_create_eval_final_render(depsgraph, scene, ob, &data_masks);
}
- else if (ob_eval != NULL) {
+ if (ob_eval != NULL) {
if (use_cage) {
return mesh_get_eval_deform(depsgraph, scene, ob_eval, &data_masks);
}
- else {
- return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks);
- }
+
+ return mesh_get_eval_final(depsgraph, scene, ob_eval, &data_masks);
}
- else {
- PyErr_Format(PyExc_ValueError,
- "%s(...): Cannot get evaluated data from given dependency graph / object pair",
- funcname);
+
+ PyErr_Format(PyExc_ValueError,
+ "%s(...): Cannot get evaluated data from given dependency graph / object pair",
+ funcname);
+ return NULL;
+ }
+
+ /* !use_deform */
+ if (use_render) {
+ if (use_cage) {
+ PyErr_Format(
+ PyExc_ValueError,
+ "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER",
+ funcname);
return NULL;
}
+
+ *r_free_mesh = true;
+ return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks);
}
- else {
- /* !use_deform */
- if (use_render) {
- if (use_cage) {
- PyErr_Format(
- PyExc_ValueError,
- "%s(...): cage arg is unsupported when dependency graph evaluation mode is RENDER",
- funcname);
- return NULL;
- }
- else {
- *r_free_mesh = true;
- return mesh_create_eval_no_deform_render(depsgraph, scene, ob, &data_masks);
- }
- }
- else {
- if (use_cage) {
- PyErr_Format(PyExc_ValueError,
- "%s(...): cage arg is unsupported when deform=False and dependency graph "
- "evaluation mode is not RENDER",
- funcname);
- return NULL;
- }
- else {
- *r_free_mesh = true;
- return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks);
- }
- }
+
+ if (use_cage) {
+ PyErr_Format(PyExc_ValueError,
+ "%s(...): cage arg is unsupported when deform=False and dependency graph "
+ "evaluation mode is not RENDER",
+ funcname);
+ return NULL;
}
+
+ *r_free_mesh = true;
+ return mesh_create_eval_no_deform(depsgraph, scene, ob, &data_masks);
}
PyDoc_STRVAR(C_BVHTree_FromObject_doc,
diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c
index 93dbac32c19..37997e9f912 100644
--- a/source/blender/python/mathutils/mathutils_geometry.c
+++ b/source/blender/python/mathutils/mathutils_geometry.c
@@ -204,12 +204,11 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject
/* collinear */
Py_RETURN_NONE;
}
- else {
- tuple = PyTuple_New(2);
- PyTuple_SET_ITEMS(
- tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL));
- return tuple;
- }
+
+ tuple = PyTuple_New(2);
+ PyTuple_SET_ITEMS(
+ tuple, Vector_CreatePyObject(i1, len, NULL), Vector_CreatePyObject(i2, len, NULL));
+ return tuple;
}
/* Line-Line intersection using algorithm from mathworld.wolfram.com */
@@ -466,9 +465,8 @@ static PyObject *M_Geometry_intersect_line_line_2d(PyObject *UNUSED(self), PyObj
if (isect_seg_seg_v2_point(UNPACK4(lines), vi) == 1) {
return Vector_CreatePyObject(vi, 2, NULL);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(
@@ -519,9 +517,8 @@ static PyObject *M_Geometry_intersect_line_plane(PyObject *UNUSED(self), PyObjec
if (isect_line_plane_v3(isect, line_a, line_b, plane_co, plane_no) == 1) {
return Vector_CreatePyObject(isect, 3, NULL);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(
@@ -637,43 +634,42 @@ static PyObject *M_Geometry_intersect_line_sphere(PyObject *UNUSED(self), PyObje
-1)) == 0) {
return NULL;
}
- else {
- bool use_a = true;
- bool use_b = true;
- float lambda;
- PyObject *ret = PyTuple_New(2);
+ bool use_a = true;
+ bool use_b = true;
+ float lambda;
- switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
- case 1:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_a = false;
- }
- use_b = false;
- break;
- case 2:
- if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_a = false;
- }
- if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_b = false;
- }
- break;
- default:
+ PyObject *ret = PyTuple_New(2);
+
+ switch (isect_line_sphere_v3(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
+ case 1:
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ use_b = false;
+ break;
+ case 2:
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
use_a = false;
+ }
+ if (!(!clip || (((lambda = line_point_factor_v3(isect_b, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
use_b = false;
- break;
- }
+ }
+ break;
+ default:
+ use_a = false;
+ use_b = false;
+ break;
+ }
- PyTuple_SET_ITEMS(ret,
- use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
- use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 3, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 3, NULL) : Py_INCREF_RET(Py_None));
- return ret;
- }
+ return ret;
}
/* keep in sync with M_Geometry_intersect_line_sphere */
@@ -723,43 +719,42 @@ static PyObject *M_Geometry_intersect_line_sphere_2d(PyObject *UNUSED(self), PyO
-1)) == 0) {
return NULL;
}
- else {
- bool use_a = true;
- bool use_b = true;
- float lambda;
- PyObject *ret = PyTuple_New(2);
+ bool use_a = true;
+ bool use_b = true;
+ float lambda;
- switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
- case 1:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_a = false;
- }
- use_b = false;
- break;
- case 2:
- if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_a = false;
- }
- if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) &&
- (lambda <= 1.0f)))) {
- use_b = false;
- }
- break;
- default:
+ PyObject *ret = PyTuple_New(2);
+
+ switch (isect_line_sphere_v2(line_a, line_b, sphere_co, sphere_radius, isect_a, isect_b)) {
+ case 1:
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
+ use_a = false;
+ }
+ use_b = false;
+ break;
+ case 2:
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_a, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
use_a = false;
+ }
+ if (!(!clip || (((lambda = line_point_factor_v2(isect_b, line_a, line_b)) >= 0.0f) &&
+ (lambda <= 1.0f)))) {
use_b = false;
- break;
- }
+ }
+ break;
+ default:
+ use_a = false;
+ use_b = false;
+ break;
+ }
- PyTuple_SET_ITEMS(ret,
- use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
- use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
+ PyTuple_SET_ITEMS(ret,
+ use_a ? Vector_CreatePyObject(isect_a, 2, NULL) : Py_INCREF_RET(Py_None),
+ use_b ? Vector_CreatePyObject(isect_b, 2, NULL) : Py_INCREF_RET(Py_None));
- return ret;
- }
+ return ret;
}
PyDoc_STRVAR(
@@ -849,9 +844,8 @@ static PyObject *M_Geometry_intersect_point_tri(PyObject *UNUSED(self), PyObject
if (isect_point_tri_v3(pt, UNPACK3(tri), vi)) {
return Vector_CreatePyObject(vi, 3, NULL);
}
- else {
- Py_RETURN_NONE;
- }
+
+ Py_RETURN_NONE;
}
PyDoc_STRVAR(M_Geometry_closest_point_on_tri_doc,
@@ -1094,88 +1088,84 @@ static PyObject *M_Geometry_points_in_planes(PyObject *UNUSED(self), PyObject *a
(float **)&planes, 4, py_planes, "points_in_planes")) == -1) {
return NULL;
}
- else {
- /* note, this could be refactored into plain C easy - py bits are noted */
- const float eps = 0.0001f;
- const uint len = (uint)planes_len;
- uint i, j, k, l;
-
- float n1n2[3], n2n3[3], n3n1[3];
- float potentialVertex[3];
- char *planes_used = PyMem_Malloc(sizeof(char) * len);
-
- /* python */
- PyObject *py_verts = PyList_New(0);
- PyObject *py_plane_index = PyList_New(0);
-
- memset(planes_used, 0, sizeof(char) * len);
-
- for (i = 0; i < len; i++) {
- const float *N1 = planes[i];
- for (j = i + 1; j < len; j++) {
- const float *N2 = planes[j];
- cross_v3_v3v3(n1n2, N1, N2);
- if (len_squared_v3(n1n2) > eps) {
- for (k = j + 1; k < len; k++) {
- const float *N3 = planes[k];
- cross_v3_v3v3(n2n3, N2, N3);
- if (len_squared_v3(n2n3) > eps) {
- cross_v3_v3v3(n3n1, N3, N1);
- if (len_squared_v3(n3n1) > eps) {
- const float quotient = dot_v3v3(N1, n2n3);
- if (fabsf(quotient) > eps) {
- /**
- * <pre>
- * potentialVertex = (
- * (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) *
- * (-1.0 / quotient));
- * </pre>
- */
- const float quotient_ninv = -1.0f / quotient;
- potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) +
- (n1n2[0] * N3[3])) *
- quotient_ninv;
- potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) +
- (n1n2[1] * N3[3])) *
- quotient_ninv;
- potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) +
- (n1n2[2] * N3[3])) *
- quotient_ninv;
- for (l = 0; l < len; l++) {
- const float *NP = planes[l];
- if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) {
- break;
- }
- }
- if (l == len) { /* ok */
- /* python */
- PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
- planes_used[i] = planes_used[j] = planes_used[k] = true;
+ /* note, this could be refactored into plain C easy - py bits are noted */
+ const float eps = 0.0001f;
+ const uint len = (uint)planes_len;
+ uint i, j, k, l;
+
+ float n1n2[3], n2n3[3], n3n1[3];
+ float potentialVertex[3];
+ char *planes_used = PyMem_Malloc(sizeof(char) * len);
+
+ /* python */
+ PyObject *py_verts = PyList_New(0);
+ PyObject *py_plane_index = PyList_New(0);
+
+ memset(planes_used, 0, sizeof(char) * len);
+
+ for (i = 0; i < len; i++) {
+ const float *N1 = planes[i];
+ for (j = i + 1; j < len; j++) {
+ const float *N2 = planes[j];
+ cross_v3_v3v3(n1n2, N1, N2);
+ if (len_squared_v3(n1n2) > eps) {
+ for (k = j + 1; k < len; k++) {
+ const float *N3 = planes[k];
+ cross_v3_v3v3(n2n3, N2, N3);
+ if (len_squared_v3(n2n3) > eps) {
+ cross_v3_v3v3(n3n1, N3, N1);
+ if (len_squared_v3(n3n1) > eps) {
+ const float quotient = dot_v3v3(N1, n2n3);
+ if (fabsf(quotient) > eps) {
+ /**
+ * <pre>
+ * potentialVertex = (
+ * (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) *
+ * (-1.0 / quotient));
+ * </pre>
+ */
+ const float quotient_ninv = -1.0f / quotient;
+ potentialVertex[0] = ((n2n3[0] * N1[3]) + (n3n1[0] * N2[3]) + (n1n2[0] * N3[3])) *
+ quotient_ninv;
+ potentialVertex[1] = ((n2n3[1] * N1[3]) + (n3n1[1] * N2[3]) + (n1n2[1] * N3[3])) *
+ quotient_ninv;
+ potentialVertex[2] = ((n2n3[2] * N1[3]) + (n3n1[2] * N2[3]) + (n1n2[2] * N3[3])) *
+ quotient_ninv;
+ for (l = 0; l < len; l++) {
+ const float *NP = planes[l];
+ if ((dot_v3v3(NP, potentialVertex) + NP[3]) > 0.000001f) {
+ break;
}
}
+
+ if (l == len) { /* ok */
+ /* python */
+ PyList_APPEND(py_verts, Vector_CreatePyObject(potentialVertex, 3, NULL));
+ planes_used[i] = planes_used[j] = planes_used[k] = true;
+ }
}
}
}
}
}
}
+ }
- PyMem_Free(planes);
+ PyMem_Free(planes);
- /* now make a list of used planes */
- for (i = 0; i < len; i++) {
- if (planes_used[i]) {
- PyList_APPEND(py_plane_index, PyLong_FromLong(i));
- }
+ /* now make a list of used planes */
+ for (i = 0; i < len; i++) {
+ if (planes_used[i]) {
+ PyList_APPEND(py_plane_index, PyLong_FromLong(i));
}
- PyMem_Free(planes_used);
+ }
+ PyMem_Free(planes_used);
- {
- PyObject *ret = PyTuple_New(2);
- PyTuple_SET_ITEMS(ret, py_verts, py_plane_index);
- return ret;
- }
+ {
+ PyObject *ret = PyTuple_New(2);
+ PyTuple_SET_ITEMS(ret, py_verts, py_plane_index);
+ return ret;
}
}
@@ -1321,7 +1311,7 @@ static PyObject *M_Geometry_tessellate_polygon(PyObject *UNUSED(self), PyObject
BKE_displist_free(&dispbase); /* possible some dl was allocated */
return NULL;
}
- else if (totpoints) {
+ if (totpoints) {
/* now make the list to return */
BKE_displist_fill(&dispbase, &dispbase, is_2d ? ((const float[3]){0, 0, -1}) : NULL, false);
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 7b28728cfe7..188bdab316c 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -491,7 +491,7 @@ static float clipx_rctf(rctf *rf, float x1, float x2)
rf->xmin = rf->xmax;
return 0.0;
}
- else if (size != 0.0f) {
+ if (size != 0.0f) {
return BLI_rctf_size_x(rf) / size;
}
return 1.0;
@@ -514,7 +514,7 @@ static float clipy_rctf(rctf *rf, float y1, float y2)
rf->ymin = rf->ymax;
return 0.0;
}
- else if (size != 0.0f) {
+ if (size != 0.0f) {
return BLI_rctf_size_y(rf) / size;
}
return 1.0;
@@ -888,7 +888,7 @@ static void ewa_read_pixel_cb(void *userdata, int x, int y, float result[4])
static void ewa_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD)
{
ReadEWAData data;
- float uv[2] = {fx, fy};
+ const float uv[2] = {fx, fy};
data.ibuf = ibuf;
data.AFD = AFD;
BLI_ewa_filter(ibuf->x,
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index b30821a1b73..f12b425ee8b 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -157,7 +157,7 @@ static void init_bake_rast(MBakeRast *bake_rast,
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
{
- float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
+ const float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
const float *st0, *st1, *st2;
const float *tang0, *tang1, *tang2;
float no0[3], no1[3], no2[3];
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index ade80898131..0fc389ecd93 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -281,9 +281,8 @@ RenderLayer *RE_GetRenderLayer(RenderResult *rr, const char *name)
if (rr == NULL) {
return NULL;
}
- else {
- return BLI_findstring(&rr->layers, name, offsetof(RenderLayer, name));
- }
+
+ return BLI_findstring(&rr->layers, name, offsetof(RenderLayer, name));
}
bool RE_HasSingleLayer(Render *re)
@@ -1655,9 +1654,8 @@ static bool check_valid_compositing_camera(Scene *scene, Object *camera_override
return true;
}
- else {
- return (camera_override != NULL || scene->camera != NULL);
- }
+
+ return (camera_override != NULL || scene->camera != NULL);
}
static bool check_valid_camera_multiview(Scene *scene, Object *camera, ReportList *reports)
@@ -1755,7 +1753,7 @@ static bool node_tree_has_composite_output(bNodeTree *ntree)
if (ELEM(node->type, CMP_NODE_COMPOSITE, CMP_NODE_OUTPUT_FILE)) {
return true;
}
- else if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
+ if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
if (node->id) {
if (node_tree_has_composite_output((bNodeTree *)node->id)) {
return true;
@@ -1879,14 +1877,14 @@ const char *RE_GetActiveRenderView(Render *re)
}
/* evaluating scene options for general Blender render */
-static int render_initialize_from_main(Render *re,
- const RenderData *rd,
- Main *bmain,
- Scene *scene,
- ViewLayer *single_layer,
- Object *camera_override,
- int anim,
- int anim_init)
+static int render_init_from_main(Render *re,
+ const RenderData *rd,
+ Main *bmain,
+ Scene *scene,
+ ViewLayer *single_layer,
+ Object *camera_override,
+ int anim,
+ int anim_init)
{
int winx, winy;
rcti disprect;
@@ -2004,8 +2002,7 @@ void RE_RenderFrame(Render *re,
scene->r.cfra = frame;
- if (render_initialize_from_main(
- re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
+ if (render_init_from_main(re, &scene->r, bmain, scene, single_layer, camera_override, 0, 0)) {
const RenderData rd = scene->r;
MEM_reset_peak_memory();
@@ -2058,7 +2055,7 @@ void RE_RenderFrame(Render *re,
void RE_RenderFreestyleStrokes(Render *re, Main *bmain, Scene *scene, int render)
{
re->result_ok = 0;
- if (render_initialize_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
+ if (render_init_from_main(re, &scene->r, bmain, scene, NULL, NULL, 0, 0)) {
if (render) {
do_render_3d(re);
}
@@ -2422,7 +2419,7 @@ void RE_RenderAnim(Render *re,
(rd.im_format.views_format == R_IMF_VIEWS_INDIVIDUAL));
/* do not fully call for each frame, it initializes & pops output window */
- if (!render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) {
+ if (!render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 0, 1)) {
return;
}
@@ -2501,15 +2498,14 @@ void RE_RenderAnim(Render *re,
render_update_depsgraph(re);
/* only border now, todo: camera lens. (ton) */
- render_initialize_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0);
+ render_init_from_main(re, &rd, bmain, scene, single_layer, camera_override, 1, 0);
if (nfra != scene->r.cfra) {
/* Skip this frame, but could update for physics and particles system. */
continue;
}
- else {
- nfra += tfra;
- }
+
+ nfra += tfra;
/* Touch/NoOverwrite options are only valid for image's */
if (is_movie == false) {
@@ -2864,7 +2860,7 @@ RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, con
if (viewname == NULL || viewname[0] == '\0') {
break;
}
- else if (STREQ(rp->view, viewname)) {
+ if (STREQ(rp->view, viewname)) {
break;
}
}
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 8daad33b477..db3ae8d8b5e 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -557,7 +557,7 @@ static float density_falloff(PointDensityRangeData *pdr, int index, float square
}
if (pdr->density_curve && dist != 0.0f) {
- BKE_curvemapping_initialize(pdr->density_curve);
+ BKE_curvemapping_init(pdr->density_curve);
density = BKE_curvemapping_evaluateF(pdr->density_curve, 0, density / dist) * dist;
}
@@ -868,7 +868,7 @@ void RE_point_density_minmax(struct Depsgraph *depsgraph,
particle_system_minmax(depsgraph, scene, object, psys, pd->radius, r_min, r_max);
}
else {
- float radius[3] = {pd->radius, pd->radius, pd->radius};
+ const float radius[3] = {pd->radius, pd->radius, pd->radius};
BoundBox *bb = BKE_object_boundbox_get(object);
if (bb != NULL) {
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 4b74bfb3e5c..6299a86e25f 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -709,7 +709,7 @@ static int order_render_passes(const void *a, const void *b)
if (passtype_a > passtype_b) {
return 1;
}
- else if (passtype_a < passtype_b) {
+ if (passtype_a < passtype_b) {
return 0;
}
}
@@ -728,7 +728,7 @@ static int order_render_passes(const void *a, const void *b)
if (STREQ(rpa->view, STEREO_LEFT_NAME)) {
return 0;
}
- else if (STREQ(rpb->view, STEREO_LEFT_NAME)) {
+ if (STREQ(rpb->view, STEREO_LEFT_NAME)) {
return 1;
}
@@ -736,7 +736,7 @@ static int order_render_passes(const void *a, const void *b)
if (STREQ(rpa->view, STEREO_RIGHT_NAME)) {
return 0;
}
- else if (STREQ(rpb->view, STEREO_RIGHT_NAME)) {
+ if (STREQ(rpb->view, STEREO_RIGHT_NAME)) {
return 1;
}
@@ -930,9 +930,8 @@ bool RE_WriteRenderResult(ReportList *reports,
if (!STREQ(view, viewname)) {
continue;
}
- else {
- viewname = "";
- }
+
+ viewname = "";
}
/* Skip compositing if only a single other layer is requested. */
@@ -993,9 +992,8 @@ bool RE_WriteRenderResult(ReportList *reports,
if (!STREQ(view, viewname)) {
continue;
}
- else {
- viewname = "";
- }
+
+ viewname = "";
}
/* We only store RGBA passes as half float, for
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index b37eeed3681..e5c62dbd784 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1381,20 +1381,19 @@ static int multitex_nodes_intern(Tex *tex,
return rgbnor;
}
- else {
- return multitex(tex,
- texvec,
- dxt,
- dyt,
- osatex,
- texres,
- thread,
- which_output,
- pool,
- skip_load_image,
- texnode_preview,
- use_nodes);
- }
+
+ return multitex(tex,
+ texvec,
+ dxt,
+ dyt,
+ osatex,
+ texres,
+ thread,
+ which_output,
+ pool,
+ skip_load_image,
+ texnode_preview,
+ use_nodes);
}
/* this is called from the shader and texture nodes
diff --git a/source/blender/simulation/CMakeLists.txt b/source/blender/simulation/CMakeLists.txt
index 243b056db74..cbc6ee65303 100644
--- a/source/blender/simulation/CMakeLists.txt
+++ b/source/blender/simulation/CMakeLists.txt
@@ -43,7 +43,9 @@ set(SRC
intern/implicit_eigen.cpp
intern/particle_allocator.cc
intern/particle_function.cc
+ intern/particle_mesh_emitter.cc
intern/simulation_collect_influences.cc
+ intern/simulation_solver_influences.cc
intern/simulation_solver.cc
intern/simulation_update.cc
@@ -52,7 +54,9 @@ set(SRC
intern/implicit.h
intern/particle_allocator.hh
intern/particle_function.hh
+ intern/particle_mesh_emitter.hh
intern/simulation_collect_influences.hh
+ intern/simulation_solver_influences.hh
intern/simulation_solver.hh
intern/time_interval.hh
diff --git a/source/blender/simulation/SIM_simulation_update.hh b/source/blender/simulation/SIM_simulation_update.hh
index 2c64fdec02e..7c2726f038e 100644
--- a/source/blender/simulation/SIM_simulation_update.hh
+++ b/source/blender/simulation/SIM_simulation_update.hh
@@ -26,4 +26,6 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
Scene *scene_cow,
Simulation *simulation_cow);
-}
+bool update_simulation_dependencies(Simulation *simulation);
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp
index c80ae69ce73..c24b7154d13 100644
--- a/source/blender/simulation/intern/hair_volume.cpp
+++ b/source/blender/simulation/intern/hair_volume.cpp
@@ -710,9 +710,8 @@ BLI_INLINE float hair_volume_density_divergence(float density,
if (density > density_threshold && density > target_density) {
return strength * logf(target_density / density);
}
- else {
- return 0.0f;
- }
+
+ return 0.0f;
}
bool SIM_hair_volume_solve_divergence(HairGrid *grid,
@@ -1030,14 +1029,13 @@ bool SIM_hair_volume_solve_divergence(HairGrid *grid,
return true;
}
- else {
- /* Clear result in case of error */
- for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) {
- zero_v3(vert->velocity_smooth);
- }
- return false;
+ /* Clear result in case of error */
+ for (i = 0, vert = grid->verts; i < num_cells; i++, vert++) {
+ zero_v3(vert->velocity_smooth);
}
+
+ return false;
}
#if 0 /* XXX weighting is incorrect, disabled for now */
diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c
index 856572aa3f5..ccc26233e3a 100644
--- a/source/blender/simulation/intern/implicit_blender.c
+++ b/source/blender/simulation/intern/implicit_blender.c
@@ -98,7 +98,7 @@ DO_INLINE void mul_fvector_S(float to[3], const float from[3], float scalar)
}
/* simple v^T * v product ("outer product") */
/* STATUS: HAS TO BE verified (*should* work) */
-DO_INLINE void mul_fvectorT_fvector(float to[3][3], float vectorA[3], float vectorB[3])
+DO_INLINE void mul_fvectorT_fvector(float to[3][3], const float vectorA[3], const float vectorB[3])
{
mul_fvector_S(to[0], vectorB, vectorA[0]);
mul_fvector_S(to[1], vectorB, vectorA[1]);
@@ -156,7 +156,7 @@ DO_INLINE void cp_lfvector(float (*to)[3], float (*from)[3], unsigned int verts)
memcpy(to, from, verts * sizeof(lfVector));
}
/* init long vector with float[3] */
-DO_INLINE void init_lfvector(float (*fLongVector)[3], float vector[3], unsigned int verts)
+DO_INLINE void init_lfvector(float (*fLongVector)[3], const float vector[3], unsigned int verts)
{
unsigned int i = 0;
for (i = 0; i < verts; i++) {
@@ -360,7 +360,7 @@ static void print_bfmatrix(fmatrix3x3 *m)
# endif
/* copy 3x3 matrix */
-DO_INLINE void cp_fmatrix(float to[3][3], float from[3][3])
+DO_INLINE void cp_fmatrix(float to[3][3], const float from[3][3])
{
// memcpy(to, from, sizeof (float) * 9);
copy_v3_v3(to[0], from[0]);
@@ -429,7 +429,7 @@ DO_INLINE void mul_fmatrix_S(float matrix[3][3], float scalar)
/* a vector multiplied by a 3x3 matrix */
/* STATUS: verified */
-DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3][3])
+DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, const float matrix[3][3])
{
to[0] = matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
to[1] = matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
@@ -438,14 +438,16 @@ DO_INLINE void mul_fvector_fmatrix(float *to, const float *from, float matrix[3]
/* 3x3 matrix multiplied by a vector */
/* STATUS: verified */
-DO_INLINE void mul_fmatrix_fvector(float *to, float matrix[3][3], float from[3])
+DO_INLINE void mul_fmatrix_fvector(float *to, const float matrix[3][3], const float from[3])
{
to[0] = dot_v3v3(matrix[0], from);
to[1] = dot_v3v3(matrix[1], from);
to[2] = dot_v3v3(matrix[2], from);
}
/* 3x3 matrix addition with 3x3 matrix */
-DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+DO_INLINE void add_fmatrix_fmatrix(float to[3][3],
+ const float matrixA[3][3],
+ const float matrixB[3][3])
{
add_v3_v3v3(to[0], matrixA[0], matrixB[0]);
add_v3_v3v3(to[1], matrixA[1], matrixB[1]);
@@ -453,14 +455,16 @@ DO_INLINE void add_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma
}
/* A -= B*x + C*y (3x3 matrix sub-addition with 3x3 matrix) */
DO_INLINE void subadd_fmatrixS_fmatrixS(
- float to[3][3], float matrixA[3][3], float aS, float matrixB[3][3], float bS)
+ float to[3][3], const float matrixA[3][3], float aS, const float matrixB[3][3], float bS)
{
VECSUBADDSS(to[0], matrixA[0], aS, matrixB[0], bS);
VECSUBADDSS(to[1], matrixA[1], aS, matrixB[1], bS);
VECSUBADDSS(to[2], matrixA[2], aS, matrixB[2], bS);
}
/* A = B - C (3x3 matrix subtraction with 3x3 matrix) */
-DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float matrixB[3][3])
+DO_INLINE void sub_fmatrix_fmatrix(float to[3][3],
+ const float matrixA[3][3],
+ const float matrixB[3][3])
{
sub_v3_v3v3(to[0], matrixA[0], matrixB[0]);
sub_v3_v3v3(to[1], matrixA[1], matrixB[1]);
@@ -471,14 +475,14 @@ DO_INLINE void sub_fmatrix_fmatrix(float to[3][3], float matrixA[3][3], float ma
/////////////////////////////////////////////////////////////////
/* 3x3 matrix multiplied+added by a vector */
/* STATUS: verified */
-DO_INLINE void muladd_fmatrix_fvector(float to[3], float matrix[3][3], float from[3])
+DO_INLINE void muladd_fmatrix_fvector(float to[3], const float matrix[3][3], const float from[3])
{
to[0] += dot_v3v3(matrix[0], from);
to[1] += dot_v3v3(matrix[1], from);
to[2] += dot_v3v3(matrix[2], from);
}
-DO_INLINE void muladd_fmatrixT_fvector(float to[3], float matrix[3][3], const float from[3])
+DO_INLINE void muladd_fmatrixT_fvector(float to[3], const float matrix[3][3], const float from[3])
{
to[0] += matrix[0][0] * from[0] + matrix[1][0] * from[1] + matrix[2][0] * from[2];
to[1] += matrix[0][1] * from[0] + matrix[1][1] * from[1] + matrix[2][1] * from[2];
@@ -492,7 +496,7 @@ BLI_INLINE void outerproduct(float r[3][3], const float a[3], const float b[3])
mul_v3_v3fl(r[2], a, b[2]);
}
-BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], float m[3][3])
+BLI_INLINE void cross_m3_v3m3(float r[3][3], const float v[3], const float m[3][3])
{
cross_v3_v3v3(r[0], v, m[0]);
cross_v3_v3v3(r[1], v, m[1]);
@@ -512,7 +516,7 @@ BLI_INLINE void cross_v3_identity(float r[3][3], const float v[3])
r[2][2] = 0.0f;
}
-BLI_INLINE void madd_m3_m3fl(float r[3][3], float m[3][3], float f)
+BLI_INLINE void madd_m3_m3fl(float r[3][3], const float m[3][3], float f)
{
r[0][0] += m[0][0] * f;
r[0][1] += m[0][1] * f;
@@ -744,7 +748,10 @@ BLI_INLINE void root_to_world_v3(Implicit_Data *data, int index, float r[3], con
mul_v3_m3v3(r, data->tfm[index].m, v);
}
-BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+BLI_INLINE void world_to_root_m3(Implicit_Data *data,
+ int index,
+ float r[3][3],
+ const float m[3][3])
{
float trot[3][3];
copy_m3_m3(trot, data->tfm[index].m);
@@ -752,7 +759,10 @@ BLI_INLINE void world_to_root_m3(Implicit_Data *data, int index, float r[3][3],
mul_m3_m3m3(r, trot, m);
}
-BLI_INLINE void root_to_world_m3(Implicit_Data *data, int index, float r[3][3], float m[3][3])
+BLI_INLINE void root_to_world_m3(Implicit_Data *data,
+ int index,
+ float r[3][3],
+ const float m[3][3])
{
mul_m3_m3m3(r, data->tfm[index].m, m);
}
@@ -1469,7 +1479,7 @@ void SIM_mass_spring_force_face_wind(
Implicit_Data *data, int v1, int v2, int v3, const float (*winvec)[3])
{
const float effector_scale = 0.02f;
- int vs[3] = {v1, v2, v3};
+ const int vs[3] = {v1, v2, v3};
float win[3], nor[3], area;
float factor, base_force;
float force[3];
@@ -1509,7 +1519,7 @@ void SIM_mass_spring_force_face_extern(
Implicit_Data *data, int v1, int v2, int v3, const float (*forcevec)[3])
{
const float effector_scale = 0.02f;
- int vs[3] = {v1, v2, v3};
+ const int vs[3] = {v1, v2, v3};
float nor[3], area;
float factor, base_force[3];
float force[3][3];
@@ -1711,9 +1721,8 @@ BLI_INLINE float fbstar(float length, float L, float kb, float cb)
if (tempfb_fl < fbstar_fl) {
return fbstar_fl;
}
- else {
- return tempfb_fl;
- }
+
+ return tempfb_fl;
}
// function to calculae bending spring force (taken from Choi & Co)
@@ -1725,9 +1734,8 @@ BLI_INLINE float fbstar_jacobi(float length, float L, float kb, float cb)
if (tempfb_fl < fbstar_fl) {
return -cb;
}
- else {
- return -kb * fbderiv(length, L);
- }
+
+ return -kb * fbderiv(length, L);
}
/* calculate elonglation */
@@ -1763,8 +1771,12 @@ BLI_INLINE bool spring_length(Implicit_Data *data,
return true;
}
-BLI_INLINE void apply_spring(
- Implicit_Data *data, int i, int j, const float f[3], float dfdx[3][3], float dfdv[3][3])
+BLI_INLINE void apply_spring(Implicit_Data *data,
+ int i,
+ int j,
+ const float f[3],
+ const float dfdx[3][3],
+ const float dfdv[3][3])
{
int block_ij = SIM_mass_spring_add_block(data, i, j);
@@ -1864,9 +1876,8 @@ bool SIM_mass_spring_force_spring_bending(
return true;
}
- else {
- return false;
- }
+
+ return false;
}
BLI_INLINE void poly_avg(lfVector *data, const int *inds, int len, float r_avg[3])
@@ -1902,7 +1913,7 @@ BLI_INLINE void edge_norm(lfVector *data, int i, int j, float r_dir[3])
normalize_v3(r_dir);
}
-BLI_INLINE float bend_angle(float dir_a[3], float dir_b[3], float dir_e[3])
+BLI_INLINE float bend_angle(const float dir_a[3], const float dir_b[3], const float dir_e[3])
{
float cos, sin;
float tmp[3];
@@ -2352,9 +2363,8 @@ bool SIM_mass_spring_force_spring_goal(Implicit_Data *data,
return true;
}
- else {
- return false;
- }
+
+ return false;
}
#endif /* IMPLICIT_SOLVER_BLENDER */
diff --git a/source/blender/simulation/intern/particle_allocator.cc b/source/blender/simulation/intern/particle_allocator.cc
index eb1e998e63a..e47a6354d81 100644
--- a/source/blender/simulation/intern/particle_allocator.cc
+++ b/source/blender/simulation/intern/particle_allocator.cc
@@ -16,6 +16,8 @@
#include "particle_allocator.hh"
+#include "BLI_rand.hh"
+
namespace blender::sim {
AttributesAllocator::~AttributesAllocator()
@@ -67,8 +69,15 @@ fn::MutableAttributesRef ParticleAllocator::allocate(int size)
ids[pindex] = start_id + pindex;
}
}
+ else if (name == "Hash") {
+ MutableSpan<int> hashes = attributes.get<int>("Hash");
+ RandomNumberGenerator rng(hash_seed_ ^ (uint32_t)next_id_);
+ for (int pindex : IndexRange(size)) {
+ hashes[pindex] = (int)rng.get_uint32();
+ }
+ }
else {
- type.fill_uninitialized(info.default_of(i), attributes.get(i).buffer(), size);
+ type.fill_uninitialized(info.default_of(i), attributes.get(i).data(), size);
}
}
return attributes;
diff --git a/source/blender/simulation/intern/particle_allocator.hh b/source/blender/simulation/intern/particle_allocator.hh
index ae23c8c8238..c0bbdb845d9 100644
--- a/source/blender/simulation/intern/particle_allocator.hh
+++ b/source/blender/simulation/intern/particle_allocator.hh
@@ -69,10 +69,11 @@ class ParticleAllocator : NonCopyable, NonMovable {
private:
AttributesAllocator attributes_allocator_;
std::atomic<int> next_id_;
+ uint32_t hash_seed_;
public:
- ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id)
- : attributes_allocator_(attributes_info), next_id_(next_id)
+ ParticleAllocator(const fn::AttributesInfo &attributes_info, int next_id, uint32_t hash_seed)
+ : attributes_allocator_(attributes_info), next_id_(next_id), hash_seed_(hash_seed)
{
}
diff --git a/source/blender/simulation/intern/particle_function.cc b/source/blender/simulation/intern/particle_function.cc
index 935ef7983d9..69977eb2054 100644
--- a/source/blender/simulation/intern/particle_function.cc
+++ b/source/blender/simulation/intern/particle_function.cc
@@ -49,19 +49,17 @@ ParticleFunction::ParticleFunction(const fn::MultiFunction *global_fn,
}
}
-ParticleFunctionEvaluator::ParticleFunctionEvaluator(
- const ParticleFunction &particle_fn,
- const SimulationSolveContext &solve_context,
- const ParticleChunkContext &particle_chunk_context)
+ParticleFunctionEvaluator::ParticleFunctionEvaluator(const ParticleFunction &particle_fn,
+ const SimulationSolveContext &solve_context,
+ const ParticleChunkContext &particles)
: particle_fn_(particle_fn),
solve_context_(solve_context),
- particle_chunk_context_(particle_chunk_context),
- mask_(particle_chunk_context_.index_mask()),
+ particles_(particles),
+ mask_(particles_.index_mask),
outputs_(particle_fn_.output_types_.size(), nullptr)
{
- global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map());
- per_particle_context_.add_global_context("PersistentDataHandleMap",
- &solve_context_.handle_map());
+ global_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
+ per_particle_context_.add_global_context("PersistentDataHandleMap", &solve_context_.handle_map);
}
ParticleFunctionEvaluator::~ParticleFunctionEvaluator()
@@ -92,8 +90,10 @@ void ParticleFunctionEvaluator::compute()
fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_name) const
{
#ifdef DEBUG
- StringRef real_name = particle_fn_.output_names_[output_index];
- BLI_assert(expected_name == real_name);
+ if (expected_name != "") {
+ StringRef real_name = particle_fn_.output_names_[output_index];
+ BLI_assert(expected_name == real_name);
+ }
BLI_assert(is_computed_);
#endif
UNUSED_VARS_NDEBUG(expected_name);
@@ -102,9 +102,8 @@ fn::GVSpan ParticleFunctionEvaluator::get(int output_index, StringRef expected_n
if (particle_fn_.output_is_global_[output_index]) {
return fn::GVSpan::FromSingleWithMaxSize(type, buffer);
}
- else {
- return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size()));
- }
+
+ return fn::GVSpan(fn::GSpan(type, buffer, mask_.min_array_size()));
}
void ParticleFunctionEvaluator::compute_globals()
@@ -116,8 +115,9 @@ void ParticleFunctionEvaluator::compute_globals()
fn::MFParamsBuilder params(*particle_fn_.global_fn_, mask_.min_array_size());
/* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
for (const ParticleFunctionInput *input : particle_fn_.global_inputs_) {
- input->add_input(particle_chunk_context_.attributes(), params, resources_);
+ input->add_input(input_context, params, resources_);
}
/* Add output parameters. */
@@ -143,8 +143,9 @@ void ParticleFunctionEvaluator::compute_per_particle()
fn::MFParamsBuilder params(*particle_fn_.per_particle_fn_, mask_.min_array_size());
/* Add input parameters. */
+ ParticleFunctionInputContext input_context{solve_context_, particles_};
for (const ParticleFunctionInput *input : particle_fn_.per_particle_inputs_) {
- input->add_input(particle_chunk_context_.attributes(), params, resources_);
+ input->add_input(input_context, params, resources_);
}
/* Add output parameters. */
diff --git a/source/blender/simulation/intern/particle_function.hh b/source/blender/simulation/intern/particle_function.hh
index cc8ccbd8243..ead4e6f3c31 100644
--- a/source/blender/simulation/intern/particle_function.hh
+++ b/source/blender/simulation/intern/particle_function.hh
@@ -25,10 +25,15 @@
namespace blender::sim {
+struct ParticleFunctionInputContext {
+ const SimulationSolveContext &solve_context;
+ const ParticleChunkContext &particles;
+};
+
class ParticleFunctionInput {
public:
virtual ~ParticleFunctionInput() = default;
- virtual void add_input(fn::AttributesRef attributes,
+ virtual void add_input(ParticleFunctionInputContext &context,
fn::MFParamsBuilder &params,
ResourceCollector &resources) const = 0;
};
@@ -60,7 +65,7 @@ class ParticleFunctionEvaluator {
ResourceCollector resources_;
const ParticleFunction &particle_fn_;
const SimulationSolveContext &solve_context_;
- const ParticleChunkContext &particle_chunk_context_;
+ const ParticleChunkContext &particles_;
IndexMask mask_;
fn::MFContextBuilder global_context_;
fn::MFContextBuilder per_particle_context_;
@@ -70,13 +75,13 @@ class ParticleFunctionEvaluator {
public:
ParticleFunctionEvaluator(const ParticleFunction &particle_fn,
const SimulationSolveContext &solve_context,
- const ParticleChunkContext &particle_chunk_context);
+ const ParticleChunkContext &particles);
~ParticleFunctionEvaluator();
void compute();
- fn::GVSpan get(int output_index, StringRef expected_name) const;
+ fn::GVSpan get(int output_index, StringRef expected_name = "") const;
- template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name) const
+ template<typename T> fn::VSpan<T> get(int output_index, StringRef expected_name = "") const
{
return this->get(output_index, expected_name).typed<T>();
}
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.cc b/source/blender/simulation/intern/particle_mesh_emitter.cc
new file mode 100644
index 00000000000..26541d550eb
--- /dev/null
+++ b/source/blender/simulation/intern/particle_mesh_emitter.cc
@@ -0,0 +1,362 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "particle_mesh_emitter.hh"
+
+#include "BLI_float4x4.hh"
+#include "BLI_rand.hh"
+#include "BLI_vector_adaptor.hh"
+
+#include "BKE_mesh_runtime.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
+
+namespace blender::sim {
+
+ParticleMeshEmitter::~ParticleMeshEmitter() = default;
+
+struct EmitterSettings {
+ Object *object;
+ float rate;
+};
+
+static BLI_NOINLINE void compute_birth_times(float rate,
+ TimeInterval emit_interval,
+ ParticleMeshEmitterSimulationState &state,
+ Vector<float> &r_birth_times)
+{
+ const float time_between_particles = 1.0f / rate;
+ int counter = 0;
+ while (true) {
+ counter++;
+ const float time_offset = counter * time_between_particles;
+ const float birth_time = state.last_birth_time + time_offset;
+ if (birth_time > emit_interval.stop()) {
+ break;
+ }
+ if (birth_time <= emit_interval.start()) {
+ continue;
+ }
+ r_birth_times.append(birth_time);
+ }
+}
+
+static BLI_NOINLINE Span<MLoopTri> get_mesh_triangles(Mesh &mesh)
+{
+ const MLoopTri *triangles = BKE_mesh_runtime_looptri_ensure(&mesh);
+ int amount = BKE_mesh_runtime_looptri_len(&mesh);
+ return Span(triangles, amount);
+}
+
+static BLI_NOINLINE void compute_triangle_areas(Mesh &mesh,
+ Span<MLoopTri> triangles,
+ MutableSpan<float> r_areas)
+{
+ assert_same_size(triangles, r_areas);
+
+ for (int i : triangles.index_range()) {
+ const MLoopTri &tri = triangles[i];
+
+ const float3 v1 = mesh.mvert[mesh.mloop[tri.tri[0]].v].co;
+ const float3 v2 = mesh.mvert[mesh.mloop[tri.tri[1]].v].co;
+ const float3 v3 = mesh.mvert[mesh.mloop[tri.tri[2]].v].co;
+
+ const float area = area_tri_v3(v1, v2, v3);
+ r_areas[i] = area;
+ }
+}
+
+static BLI_NOINLINE void compute_triangle_weights(Mesh &mesh,
+ Span<MLoopTri> triangles,
+ MutableSpan<float> r_weights)
+{
+ assert_same_size(triangles, r_weights);
+ compute_triangle_areas(mesh, triangles, r_weights);
+}
+
+static BLI_NOINLINE void compute_cumulative_distribution(Span<float> weights,
+ MutableSpan<float> r_cumulative_weights)
+{
+ BLI_assert(weights.size() + 1 == r_cumulative_weights.size());
+
+ r_cumulative_weights[0] = 0;
+ for (int i : weights.index_range()) {
+ r_cumulative_weights[i + 1] = r_cumulative_weights[i] + weights[i];
+ }
+}
+
+static void sample_cumulative_distribution_recursive(RandomNumberGenerator &rng,
+ int amount,
+ int start,
+ int one_after_end,
+ Span<float> cumulative_weights,
+ VectorAdaptor<int> &r_sampled_indices)
+{
+ BLI_assert(start <= one_after_end);
+ const int size = one_after_end - start;
+ if (size == 0) {
+ BLI_assert(amount == 0);
+ }
+ else if (amount == 0) {
+ return;
+ }
+ else if (size == 1) {
+ r_sampled_indices.append_n_times(start, amount);
+ }
+ else {
+ const int middle = start + size / 2;
+ const float left_weight = cumulative_weights[middle] - cumulative_weights[start];
+ const float right_weight = cumulative_weights[one_after_end] - cumulative_weights[middle];
+ BLI_assert(left_weight >= 0.0f && right_weight >= 0.0f);
+ const float weight_sum = left_weight + right_weight;
+ BLI_assert(weight_sum > 0.0f);
+
+ const float left_factor = left_weight / weight_sum;
+ const float right_factor = right_weight / weight_sum;
+
+ int left_amount = amount * left_factor;
+ int right_amount = amount * right_factor;
+
+ if (left_amount + right_amount < amount) {
+ BLI_assert(left_amount + right_amount + 1 == amount);
+ const float weight_per_item = weight_sum / amount;
+ const float total_remaining_weight = weight_sum -
+ (left_amount + right_amount) * weight_per_item;
+ const float left_remaining_weight = left_weight - left_amount * weight_per_item;
+ const float left_remaining_factor = left_remaining_weight / total_remaining_weight;
+ if (rng.get_float() < left_remaining_factor) {
+ left_amount++;
+ }
+ else {
+ right_amount++;
+ }
+ }
+
+ sample_cumulative_distribution_recursive(
+ rng, left_amount, start, middle, cumulative_weights, r_sampled_indices);
+ sample_cumulative_distribution_recursive(
+ rng, right_amount, middle, one_after_end, cumulative_weights, r_sampled_indices);
+ }
+}
+
+static BLI_NOINLINE void sample_cumulative_distribution(RandomNumberGenerator &rng,
+ Span<float> cumulative_weights,
+ MutableSpan<int> r_samples)
+{
+ VectorAdaptor<int> sampled_indices(r_samples);
+ sample_cumulative_distribution_recursive(rng,
+ r_samples.size(),
+ 0,
+ cumulative_weights.size() - 1,
+ cumulative_weights,
+ sampled_indices);
+ BLI_assert(sampled_indices.is_full());
+}
+
+static BLI_NOINLINE bool sample_weighted_buckets(RandomNumberGenerator &rng,
+ Span<float> weights,
+ MutableSpan<int> r_samples)
+{
+ Array<float> cumulative_weights(weights.size() + 1);
+ compute_cumulative_distribution(weights, cumulative_weights);
+
+ if (r_samples.size() > 0 && cumulative_weights.as_span().last() == 0.0f) {
+ /* All weights are zero. */
+ return false;
+ }
+
+ sample_cumulative_distribution(rng, cumulative_weights, r_samples);
+ return true;
+}
+
+static BLI_NOINLINE void sample_looptris(RandomNumberGenerator &rng,
+ Mesh &mesh,
+ Span<MLoopTri> triangles,
+ Span<int> triangles_to_sample,
+ MutableSpan<float3> r_sampled_positions,
+ MutableSpan<float3> r_sampled_normals)
+{
+ assert_same_size(triangles_to_sample, r_sampled_positions, r_sampled_normals);
+
+ MLoop *loops = mesh.mloop;
+ MVert *verts = mesh.mvert;
+
+ for (uint i : triangles_to_sample.index_range()) {
+ const uint triangle_index = triangles_to_sample[i];
+ const MLoopTri &triangle = triangles[triangle_index];
+
+ const float3 v1 = verts[loops[triangle.tri[0]].v].co;
+ const float3 v2 = verts[loops[triangle.tri[1]].v].co;
+ const float3 v3 = verts[loops[triangle.tri[2]].v].co;
+
+ const float3 bary_coords = rng.get_barycentric_coordinates();
+
+ float3 position;
+ interp_v3_v3v3v3(position, v1, v2, v3, bary_coords);
+
+ float3 normal;
+ normal_tri_v3(normal, v1, v2, v3);
+
+ r_sampled_positions[i] = position;
+ r_sampled_normals[i] = normal;
+ }
+}
+
+static BLI_NOINLINE bool compute_new_particle_attributes(ParticleEmitterContext &context,
+ EmitterSettings &settings,
+ ParticleMeshEmitterSimulationState &state,
+ Vector<float3> &r_positions,
+ Vector<float3> &r_velocities,
+ Vector<float> &r_birth_times)
+{
+ if (settings.object == nullptr) {
+ return false;
+ }
+ if (settings.rate <= 0.000001f) {
+ return false;
+ }
+ if (settings.object->type != OB_MESH) {
+ return false;
+ }
+ Mesh &mesh = *(Mesh *)settings.object->data;
+ if (mesh.totvert == 0) {
+ return false;
+ }
+
+ const float start_time = context.emit_interval.start();
+ const uint32_t seed = DefaultHash<StringRef>{}(state.head.name);
+ RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed};
+
+ compute_birth_times(settings.rate, context.emit_interval, state, r_birth_times);
+ const int particle_amount = r_birth_times.size();
+ if (particle_amount == 0) {
+ return false;
+ }
+
+ const float last_birth_time = r_birth_times.last();
+ rng.shuffle(r_birth_times.as_mutable_span());
+
+ Span<MLoopTri> triangles = get_mesh_triangles(mesh);
+ if (triangles.is_empty()) {
+ return false;
+ }
+
+ Array<float> triangle_weights(triangles.size());
+ compute_triangle_weights(mesh, triangles, triangle_weights);
+
+ Array<int> triangles_to_sample(particle_amount);
+ if (!sample_weighted_buckets(rng, triangle_weights, triangles_to_sample)) {
+ return false;
+ }
+
+ r_positions.resize(particle_amount);
+ r_velocities.resize(particle_amount);
+ sample_looptris(rng, mesh, triangles, triangles_to_sample, r_positions, r_velocities);
+
+ if (context.solve_context.dependency_animations.is_object_transform_changing(*settings.object)) {
+ Array<float4x4> local_to_world_matrices(particle_amount);
+ context.solve_context.dependency_animations.get_object_transforms(
+ *settings.object, r_birth_times, local_to_world_matrices);
+
+ for (int i : IndexRange(particle_amount)) {
+ const float4x4 &position_to_world = local_to_world_matrices[i];
+ const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+ r_positions[i] = position_to_world * r_positions[i];
+ r_velocities[i] = normal_to_world * r_velocities[i];
+ }
+ }
+ else {
+ const float4x4 position_to_world = settings.object->obmat;
+ const float4x4 normal_to_world = position_to_world.inverted_transposed_affine();
+ for (int i : IndexRange(particle_amount)) {
+ r_positions[i] = position_to_world * r_positions[i];
+ r_velocities[i] = normal_to_world * r_velocities[i];
+ }
+ }
+
+ for (int i : IndexRange(particle_amount)) {
+ r_velocities[i].normalize();
+ }
+
+ state.last_birth_time = last_birth_time;
+ return true;
+}
+
+static BLI_NOINLINE EmitterSettings compute_settings(const fn::MultiFunction &inputs_fn,
+ ParticleEmitterContext &context)
+{
+ EmitterSettings parameters;
+
+ fn::MFContextBuilder mf_context;
+ mf_context.add_global_context("PersistentDataHandleMap", &context.solve_context.handle_map);
+
+ fn::MFParamsBuilder mf_params{inputs_fn, 1};
+ bke::PersistentObjectHandle object_handle;
+ mf_params.add_uninitialized_single_output(&object_handle, "Object");
+ mf_params.add_uninitialized_single_output(&parameters.rate, "Rate");
+
+ inputs_fn.call(IndexRange(1), mf_params, mf_context);
+
+ parameters.object = context.solve_context.handle_map.lookup(object_handle);
+ return parameters;
+}
+
+void ParticleMeshEmitter::emit(ParticleEmitterContext &context) const
+{
+ auto *state = context.lookup_state<ParticleMeshEmitterSimulationState>(own_state_name_);
+ if (state == nullptr) {
+ return;
+ }
+
+ EmitterSettings settings = compute_settings(inputs_fn_, context);
+
+ Vector<float3> new_positions;
+ Vector<float3> new_velocities;
+ Vector<float> new_birth_times;
+
+ if (!compute_new_particle_attributes(
+ context, settings, *state, new_positions, new_velocities, new_birth_times)) {
+ return;
+ }
+
+ for (StringRef name : particle_names_) {
+ ParticleAllocator *allocator = context.try_get_particle_allocator(name);
+ if (allocator == nullptr) {
+ continue;
+ }
+
+ int amount = new_positions.size();
+ fn::MutableAttributesRef attributes = allocator->allocate(amount);
+
+ attributes.get<float3>("Position").copy_from(new_positions);
+ attributes.get<float3>("Velocity").copy_from(new_velocities);
+ attributes.get<float>("Birth Time").copy_from(new_birth_times);
+
+ if (action_ != nullptr) {
+ ParticleChunkContext particles{
+ *context.solve_context.state_map.lookup<ParticleSimulationState>(name),
+ IndexRange(amount),
+ attributes,
+ nullptr};
+ ParticleActionContext action_context{context.solve_context, particles};
+ action_->execute(action_context);
+ }
+ }
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/particle_mesh_emitter.hh b/source/blender/simulation/intern/particle_mesh_emitter.hh
new file mode 100644
index 00000000000..cdcf2a34e16
--- /dev/null
+++ b/source/blender/simulation/intern/particle_mesh_emitter.hh
@@ -0,0 +1,49 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "simulation_solver_influences.hh"
+
+#include "FN_multi_function.hh"
+
+namespace blender::sim {
+
+class ParticleMeshEmitter final : public ParticleEmitter {
+ private:
+ std::string own_state_name_;
+ Array<std::string> particle_names_;
+ const fn::MultiFunction &inputs_fn_;
+ const ParticleAction *action_;
+
+ public:
+ ParticleMeshEmitter(std::string own_state_name,
+ Array<std::string> particle_names,
+ const fn::MultiFunction &inputs_fn,
+ const ParticleAction *action)
+ : own_state_name_(std::move(own_state_name)),
+ particle_names_(particle_names),
+ inputs_fn_(inputs_fn),
+ action_(action)
+ {
+ }
+
+ ~ParticleMeshEmitter();
+
+ void emit(ParticleEmitterContext &context) const override;
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_collect_influences.cc b/source/blender/simulation/intern/simulation_collect_influences.cc
index 764e587d157..818415e5d88 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.cc
+++ b/source/blender/simulation/intern/simulation_collect_influences.cc
@@ -16,6 +16,7 @@
#include "simulation_collect_influences.hh"
#include "particle_function.hh"
+#include "particle_mesh_emitter.hh"
#include "FN_attributes_ref.hh"
#include "FN_multi_function_network_evaluation.hh"
@@ -23,38 +24,125 @@
#include "NOD_node_tree_multi_function.hh"
+#include "DEG_depsgraph_query.h"
+
+#include "BLI_hash.h"
#include "BLI_rand.hh"
+#include "BLI_set.hh"
namespace blender::sim {
+using fn::GVSpan;
+using fn::MFContextBuilder;
+using fn::MFDataType;
+using fn::MFDummyNode;
+using fn::MFFunctionNode;
+using fn::MFInputSocket;
+using fn::MFNetwork;
+using fn::MFNetworkEvaluator;
+using fn::MFNode;
+using fn::MFOutputSocket;
+using fn::MFParamsBuilder;
+using fn::MFParamType;
+using fn::MultiFunction;
+using fn::VSpan;
+using nodes::DerivedNodeTree;
+using nodes::DInputSocket;
+using nodes::DNode;
+using nodes::DOutputSocket;
+using nodes::DParentNode;
+using nodes::MFNetworkTreeMap;
+using nodes::NodeTreeRefMap;
+
struct DummyDataSources {
- Map<const fn::MFOutputSocket *, std::string> particle_attributes;
+ Map<const MFOutputSocket *, std::string> particle_attributes;
+ Set<const MFOutputSocket *> simulation_time;
+ Set<const MFOutputSocket *> scene_time;
};
extern "C" {
void WM_clipboard_text_set(const char *buf, bool selection);
}
-static std::string dnode_to_path(const nodes::DNode &dnode)
+static std::string dnode_to_path(const DNode &dnode)
{
std::string path;
- for (const nodes::DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) {
+ for (const DParentNode *parent = dnode.parent(); parent; parent = parent->parent()) {
path = parent->node_ref().name() + "/" + path;
}
path = path + dnode.name();
return path;
}
-static Span<const nodes::DNode *> get_particle_simulation_nodes(const nodes::DerivedNodeTree &tree)
+struct CollectContext : NonCopyable, NonMovable {
+ SimulationInfluences &influences;
+ RequiredStates &required_states;
+ ResourceCollector &resources;
+ MFNetworkTreeMap &network_map;
+ MFNetwork &network;
+ const DerivedNodeTree &tree;
+
+ DummyDataSources data_sources;
+ Span<const DNode *> particle_simulation_nodes;
+ Map<const DNode *, std::string> node_paths;
+
+ CollectContext(SimulationInfluences &influences,
+ RequiredStates &required_states,
+ ResourceCollector &resources,
+ MFNetworkTreeMap &network_map)
+ : influences(influences),
+ required_states(required_states),
+ resources(resources),
+ network_map(network_map),
+ network(network_map.network()),
+ tree(network_map.tree())
+ {
+ particle_simulation_nodes = tree.nodes_by_type("SimulationNodeParticleSimulation");
+ }
+};
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names);
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DInputSocket &dsocket,
+ Span<StringRefNull> particle_names)
+{
+ BLI_assert(dsocket.bsocket()->type == SOCK_CONTROL_FLOW);
+ if (dsocket.linked_sockets().size() != 1) {
+ return nullptr;
+ }
+ return create_particle_action(context, *dsocket.linked_sockets()[0], particle_names);
+}
+
+static StringRefNull get_identifier(CollectContext &context, const DNode &dnode)
+{
+ return context.node_paths.lookup_or_add_cb(&dnode, [&]() { return dnode_to_path(dnode); });
+}
+
+static Span<const DNode *> nodes_by_type(CollectContext &context, StringRefNull idname)
{
- return tree.nodes_by_type("SimulationNodeParticleSimulation");
+ return context.tree.nodes_by_type(idname);
+}
+
+static Array<StringRefNull> find_linked_particle_simulations(CollectContext &context,
+ const DOutputSocket &output_socket)
+{
+ VectorSet<StringRefNull> names;
+ for (const DInputSocket *target_socket : output_socket.linked_sockets()) {
+ if (target_socket->node().idname() == "SimulationNodeParticleSimulation") {
+ names.add(get_identifier(context, target_socket->node()));
+ }
+ }
+ return names.as_span();
}
/* Returns true on success. */
-static bool compute_global_inputs(nodes::MFNetworkTreeMap &network_map,
+static bool compute_global_inputs(MFNetworkTreeMap &network_map,
ResourceCollector &resources,
- Span<const fn::MFInputSocket *> sockets,
- MutableSpan<fn::GMutableSpan> r_results)
+ Span<const MFInputSocket *> sockets,
+ MutableSpan<GMutableSpan> r_results)
{
int amount = sockets.size();
if (amount == 0) {
@@ -65,28 +153,28 @@ static bool compute_global_inputs(nodes::MFNetworkTreeMap &network_map,
return false;
}
- fn::MFNetworkEvaluator network_fn{{}, sockets};
- fn::MFParamsBuilder params{network_fn, 1};
+ MFNetworkEvaluator network_fn{{}, sockets};
+ MFParamsBuilder params{network_fn, 1};
for (int param_index : network_fn.param_indices()) {
- fn::MFParamType param_type = network_fn.param_type(param_index);
- BLI_assert(param_type.category() == fn::MFParamType::Category::SingleOutput); /* For now. */
- const fn::CPPType &type = param_type.data_type().single_type();
+ MFParamType param_type = network_fn.param_type(param_index);
+ BLI_assert(param_type.category() == MFParamType::Category::SingleOutput); /* For now. */
+ const CPPType &type = param_type.data_type().single_type();
void *buffer = resources.linear_allocator().allocate(type.size(), type.alignment());
resources.add(buffer, type.destruct_cb(), AT);
- fn::GMutableSpan span{type, buffer, 1};
+ GMutableSpan span{type, buffer, 1};
r_results[param_index] = span;
params.add_uninitialized_single_output(span);
}
- fn::MFContextBuilder context;
+ MFContextBuilder context;
network_fn.call(IndexRange(1), params, context);
return true;
}
static std::optional<Array<std::string>> compute_global_string_inputs(
- nodes::MFNetworkTreeMap &network_map, Span<const fn::MFInputSocket *> sockets)
+ MFNetworkTreeMap &network_map, Span<const MFInputSocket *> sockets)
{
ResourceCollector local_resources;
- Array<fn::GMutableSpan> computed_values(sockets.size(), NoInitialization());
+ Array<GMutableSpan> computed_values(sockets.size(), NoInitialization());
if (!compute_global_inputs(network_map, local_resources, sockets, computed_values)) {
return {};
}
@@ -98,107 +186,177 @@ static std::optional<Array<std::string>> compute_global_string_inputs(
return strings;
}
-static void find_and_deduplicate_particle_attribute_nodes(nodes::MFNetworkTreeMap &network_map,
- DummyDataSources &r_data_sources)
+/**
+ * This will find all the particle attribute input nodes. Then it will compute the attribute names
+ * by evaluating the network (those names should not depend on per particle data). In the end,
+ * input nodes that access the same attribute are combined.
+ */
+static void prepare_particle_attribute_nodes(CollectContext &context)
{
- fn::MFNetwork &network = network_map.network();
- const nodes::DerivedNodeTree &tree = network_map.tree();
-
- Span<const nodes::DNode *> attribute_dnodes = tree.nodes_by_type(
- "SimulationNodeParticleAttribute");
+ Span<const DNode *> attribute_dnodes = nodes_by_type(context, "SimulationNodeParticleAttribute");
- Vector<fn::MFInputSocket *> name_sockets;
- for (const nodes::DNode *dnode : attribute_dnodes) {
- fn::MFInputSocket &name_socket = network_map.lookup_dummy(dnode->input(0));
+ Vector<MFInputSocket *> name_sockets;
+ for (const DNode *dnode : attribute_dnodes) {
+ MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode->input(0));
name_sockets.append(&name_socket);
}
- std::optional<Array<std::string>> attribute_names = compute_global_string_inputs(network_map,
- name_sockets);
+ std::optional<Array<std::string>> attribute_names = compute_global_string_inputs(
+ context.network_map, name_sockets);
if (!attribute_names.has_value()) {
return;
}
- Map<std::pair<std::string, fn::MFDataType>, Vector<fn::MFNode *>>
- attribute_nodes_by_name_and_type;
+ MultiValueMap<std::pair<std::string, MFDataType>, MFNode *> attribute_nodes_by_name_and_type;
for (int i : attribute_names->index_range()) {
- attribute_nodes_by_name_and_type
- .lookup_or_add_default(
- {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()})
- .append(&name_sockets[i]->node());
+ attribute_nodes_by_name_and_type.add(
+ {(*attribute_names)[i], name_sockets[i]->node().output(0).data_type()},
+ &name_sockets[i]->node());
}
- Map<const fn::MFOutputSocket *, std::string> attribute_inputs;
+ Map<const MFOutputSocket *, std::string> attribute_inputs;
for (auto item : attribute_nodes_by_name_and_type.items()) {
StringRef attribute_name = item.key.first;
- fn::MFDataType data_type = item.key.second;
- Span<fn::MFNode *> nodes = item.value;
+ MFDataType data_type = item.key.second;
+ Span<MFNode *> nodes = item.value;
- fn::MFOutputSocket &new_attribute_socket = network.add_input(
+ MFOutputSocket &new_attribute_socket = context.network.add_input(
"Attribute '" + attribute_name + "'", data_type);
- for (fn::MFNode *node : nodes) {
- network.relink(node->output(0), new_attribute_socket);
+ for (MFNode *node : nodes) {
+ context.network.relink(node->output(0), new_attribute_socket);
}
- network.remove(nodes);
+ context.network.remove(nodes);
- r_data_sources.particle_attributes.add_new(&new_attribute_socket, attribute_name);
+ context.data_sources.particle_attributes.add_new(&new_attribute_socket, attribute_name);
+ }
+}
+
+static void prepare_time_input_nodes(CollectContext &context)
+{
+ Span<const DNode *> time_input_dnodes = nodes_by_type(context, "SimulationNodeTime");
+ Vector<const DNode *> simulation_time_inputs;
+ Vector<const DNode *> scene_time_inputs;
+ for (const DNode *dnode : time_input_dnodes) {
+ NodeSimInputTimeType type = (NodeSimInputTimeType)dnode->node_ref().bnode()->custom1;
+ switch (type) {
+ case NODE_SIM_INPUT_SIMULATION_TIME: {
+ simulation_time_inputs.append(dnode);
+ break;
+ }
+ case NODE_SIM_INPUT_SCENE_TIME: {
+ scene_time_inputs.append(dnode);
+ break;
+ }
+ }
+ }
+
+ if (simulation_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Simulation Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : simulation_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.simulation_time.add(&new_socket);
+ }
+ if (scene_time_inputs.size() > 0) {
+ MFOutputSocket &new_socket = context.network.add_input("Scene Time",
+ MFDataType::ForSingle<float>());
+ for (const DNode *dnode : scene_time_inputs) {
+ MFOutputSocket &old_socket = context.network_map.lookup_dummy(dnode->output(0));
+ context.network.relink(old_socket, new_socket);
+ context.network.remove(old_socket.node());
+ }
+ context.data_sources.scene_time.add(&new_socket);
}
}
class ParticleAttributeInput : public ParticleFunctionInput {
private:
std::string attribute_name_;
- const fn::CPPType &attribute_type_;
+ const CPPType &attribute_type_;
public:
- ParticleAttributeInput(std::string attribute_name, const fn::CPPType &attribute_type)
+ ParticleAttributeInput(std::string attribute_name, const CPPType &attribute_type)
: attribute_name_(std::move(attribute_name)), attribute_type_(attribute_type)
{
}
- void add_input(fn::AttributesRef attributes,
- fn::MFParamsBuilder &params,
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
ResourceCollector &UNUSED(resources)) const override
{
- std::optional<fn::GSpan> span = attributes.try_get(attribute_name_, attribute_type_);
+ std::optional<GSpan> span = context.particles.attributes.try_get(attribute_name_,
+ attribute_type_);
if (span.has_value()) {
params.add_readonly_single_input(*span);
}
else {
- params.add_readonly_single_input(fn::GVSpan::FromDefault(attribute_type_));
+ params.add_readonly_single_input(GVSpan::FromDefault(attribute_type_));
}
}
};
+class SceneTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ const float time = DEG_get_ctime(&context.solve_context.depsgraph);
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
+class SimulationTimeInput : public ParticleFunctionInput {
+ void add_input(ParticleFunctionInputContext &context,
+ MFParamsBuilder &params,
+ ResourceCollector &resources) const override
+ {
+ /* TODO: Vary this per particle. */
+ const float time = context.solve_context.solve_interval.stop();
+ float *time_ptr = &resources.construct<float>(AT, time);
+ params.add_readonly_single_input(time_ptr);
+ }
+};
+
static const ParticleFunction *create_particle_function_for_inputs(
- Span<const fn::MFInputSocket *> sockets_to_compute,
- ResourceCollector &resources,
- DummyDataSources &data_sources)
+ CollectContext &context, Span<const MFInputSocket *> sockets_to_compute)
{
BLI_assert(sockets_to_compute.size() >= 1);
- const fn::MFNetwork &network = sockets_to_compute[0]->node().network();
+ const MFNetwork &network = sockets_to_compute[0]->node().network();
- VectorSet<const fn::MFOutputSocket *> dummy_deps;
- VectorSet<const fn::MFInputSocket *> unlinked_input_deps;
+ VectorSet<const MFOutputSocket *> dummy_deps;
+ VectorSet<const MFInputSocket *> unlinked_input_deps;
network.find_dependencies(sockets_to_compute, dummy_deps, unlinked_input_deps);
BLI_assert(unlinked_input_deps.size() == 0);
Vector<const ParticleFunctionInput *> per_particle_inputs;
- for (const fn::MFOutputSocket *socket : dummy_deps) {
- const std::string *attribute_name = data_sources.particle_attributes.lookup_ptr(socket);
- if (attribute_name == nullptr) {
- return nullptr;
+ for (const MFOutputSocket *socket : dummy_deps) {
+ if (context.data_sources.particle_attributes.contains(socket)) {
+ const std::string *attribute_name = context.data_sources.particle_attributes.lookup_ptr(
+ socket);
+ if (attribute_name == nullptr) {
+ return nullptr;
+ }
+ per_particle_inputs.append(&context.resources.construct<ParticleAttributeInput>(
+ AT, *attribute_name, socket->data_type().single_type()));
+ }
+ else if (context.data_sources.scene_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SceneTimeInput>(AT));
+ }
+ else if (context.data_sources.simulation_time.contains(socket)) {
+ per_particle_inputs.append(&context.resources.construct<SimulationTimeInput>(AT));
}
- per_particle_inputs.append(&resources.construct<ParticleAttributeInput>(
- AT, *attribute_name, socket->data_type().single_type()));
}
- const fn::MultiFunction &per_particle_fn = resources.construct<fn::MFNetworkEvaluator>(
+ const MultiFunction &per_particle_fn = context.resources.construct<MFNetworkEvaluator>(
AT, dummy_deps.as_span(), sockets_to_compute);
Array<bool> output_is_global(sockets_to_compute.size(), false);
- const ParticleFunction &particle_fn = resources.construct<ParticleFunction>(
+ const ParticleFunction &particle_fn = context.resources.construct<ParticleFunction>(
AT,
nullptr,
&per_particle_fn,
@@ -209,6 +367,17 @@ static const ParticleFunction *create_particle_function_for_inputs(
return &particle_fn;
}
+static const ParticleFunction *create_particle_function_for_inputs(
+ CollectContext &context, Span<const DInputSocket *> dsockets_to_compute)
+{
+ Vector<const MFInputSocket *> sockets_to_compute;
+ for (const DInputSocket *dsocket : dsockets_to_compute) {
+ const MFInputSocket &socket = context.network_map.lookup_dummy(*dsocket);
+ sockets_to_compute.append(&socket);
+ }
+ return create_particle_function_for_inputs(context, sockets_to_compute);
+}
+
class ParticleFunctionForce : public ParticleForce {
private:
const ParticleFunction &particle_fn_;
@@ -220,13 +389,12 @@ class ParticleFunctionForce : public ParticleForce {
void add_force(ParticleForceContext &context) const override
{
- IndexMask mask = context.particle_chunk().index_mask();
- MutableSpan<float3> r_combined_force = context.force_dst();
+ IndexMask mask = context.particles.index_mask;
+ MutableSpan<float3> r_combined_force = context.force_dst;
- ParticleFunctionEvaluator evaluator{
- particle_fn_, context.solve_context(), context.particle_chunk()};
+ ParticleFunctionEvaluator evaluator{particle_fn_, context.solve_context, context.particles};
evaluator.compute();
- fn::VSpan<float3> forces = evaluator.get<float3>(0, "Force");
+ VSpan<float3> forces = evaluator.get<float3>(0, "Force");
for (int64_t i : mask) {
r_combined_force[i] += forces[i];
@@ -234,218 +402,473 @@ class ParticleFunctionForce : public ParticleForce {
}
};
-static Vector<const ParticleForce *> create_forces_for_particle_simulation(
- const nodes::DNode &simulation_node,
- nodes::MFNetworkTreeMap &network_map,
- ResourceCollector &resources,
- DummyDataSources &data_sources)
+static void create_forces_for_particle_simulation(CollectContext &context,
+ const DNode &simulation_node)
{
Vector<const ParticleForce *> forces;
- for (const nodes::DOutputSocket *origin_socket :
- simulation_node.input(2, "Forces").linked_sockets()) {
- const nodes::DNode &origin_node = origin_socket->node();
+ for (const DOutputSocket *origin_socket : simulation_node.input(2, "Forces").linked_sockets()) {
+ const DNode &origin_node = origin_socket->node();
if (origin_node.idname() != "SimulationNodeForce") {
continue;
}
- const fn::MFInputSocket &force_socket = network_map.lookup_dummy(
- origin_node.input(0, "Force"));
-
const ParticleFunction *particle_fn = create_particle_function_for_inputs(
- {&force_socket}, resources, data_sources);
+ context, {&origin_node.input(0, "Force")});
if (particle_fn == nullptr) {
continue;
}
- const ParticleForce &force = resources.construct<ParticleFunctionForce>(AT, *particle_fn);
+ const ParticleForce &force = context.resources.construct<ParticleFunctionForce>(AT,
+ *particle_fn);
forces.append(&force);
}
- return forces;
+
+ StringRef particle_name = get_identifier(context, simulation_node);
+ context.influences.particle_forces.add_multiple_as(particle_name, forces);
+}
+
+static void collect_forces(CollectContext &context)
+{
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ create_forces_for_particle_simulation(context, *dnode);
+ }
+}
+
+static ParticleEmitter *create_particle_emitter(CollectContext &context, const DNode &dnode)
+{
+ Array<StringRefNull> names = find_linked_particle_simulations(context, dnode.output(0));
+ if (names.size() == 0) {
+ return nullptr;
+ }
+
+ Array<const MFInputSocket *> input_sockets{2};
+ for (int i : input_sockets.index_range()) {
+ input_sockets[i] = &context.network_map.lookup_dummy(dnode.input(i));
+ }
+
+ if (context.network.have_dummy_or_unlinked_dependencies(input_sockets)) {
+ return nullptr;
+ }
+
+ MultiFunction &inputs_fn = context.resources.construct<MFNetworkEvaluator>(
+ AT, Span<const MFOutputSocket *>(), input_sockets.as_span());
+
+ const ParticleAction *birth_action = create_particle_action(
+ context, dnode.input(2, "Execute"), names);
+
+ StringRefNull own_state_name = get_identifier(context, dnode);
+ context.required_states.add(own_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER);
+ ParticleEmitter &emitter = context.resources.construct<ParticleMeshEmitter>(
+ AT, own_state_name, names.as_span(), inputs_fn, birth_action);
+ return &emitter;
+}
+
+static void collect_emitters(CollectContext &context)
+{
+ for (const DNode *dnode : nodes_by_type(context, "SimulationNodeParticleMeshEmitter")) {
+ ParticleEmitter *emitter = create_particle_emitter(context, *dnode);
+ if (emitter != nullptr) {
+ context.influences.particle_emitters.append(emitter);
+ }
+ }
}
-static void collect_forces(nodes::MFNetworkTreeMap &network_map,
- ResourceCollector &resources,
- DummyDataSources &data_sources,
- SimulationInfluences &r_influences)
+static void collect_birth_events(CollectContext &context)
{
- for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) {
- std::string name = dnode_to_path(*dnode);
- Vector<const ParticleForce *> forces = create_forces_for_particle_simulation(
- *dnode, network_map, resources, data_sources);
- r_influences.particle_forces.add_new(std::move(name), std::move(forces));
+ for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleBirthEvent")) {
+ const DInputSocket &execute_input = event_dnode->input(0);
+ if (execute_input.linked_sockets().size() != 1) {
+ continue;
+ }
+
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ event_dnode->output(0));
+
+ const DOutputSocket &execute_source = *execute_input.linked_sockets()[0];
+ const ParticleAction *action = create_particle_action(context, execute_source, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_birth_actions.add_as(particle_name, action);
+ }
+ }
+}
+
+static void collect_time_step_events(CollectContext &context)
+{
+ for (const DNode *event_dnode : nodes_by_type(context, "SimulationNodeParticleTimeStepEvent")) {
+ const DInputSocket &execute_input = event_dnode->input(0);
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ event_dnode->output(0));
+
+ const ParticleAction *action = create_particle_action(context, execute_input, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+
+ NodeSimParticleTimeStepEventType type =
+ (NodeSimParticleTimeStepEventType)event_dnode->node_ref().bnode()->custom1;
+ if (type == NODE_PARTICLE_TIME_STEP_EVENT_BEGIN) {
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_time_step_begin_actions.add_as(particle_name, action);
+ }
+ }
+ else {
+ for (StringRefNull particle_name : particle_names) {
+ context.influences.particle_time_step_end_actions.add_as(particle_name, action);
+ }
+ }
}
}
-class MyBasicEmitter : public ParticleEmitter {
+class SequenceParticleAction : public ParticleAction {
private:
- Array<std::string> names_;
- std::string my_state_;
- const fn::MultiFunction &inputs_fn_;
- uint32_t seed_;
+ Vector<const ParticleAction *> actions_;
public:
- MyBasicEmitter(Array<std::string> names,
- std::string my_state,
- const fn::MultiFunction &inputs_fn,
- uint32_t seed)
- : names_(std::move(names)),
- my_state_(std::move(my_state)),
- inputs_fn_(inputs_fn),
- seed_(seed)
+ SequenceParticleAction(Span<const ParticleAction *> actions) : actions_(std::move(actions))
{
}
- void emit(ParticleEmitterContext &context) const override
+ void execute(ParticleActionContext &context) const override
{
- auto *state = context.solve_context().state_map().lookup<ParticleMeshEmitterSimulationState>(
- my_state_);
- if (state == nullptr) {
- return;
+ for (const ParticleAction *action : actions_) {
+ action->execute(context);
}
+ }
+};
- fn::MFContextBuilder mf_context;
- mf_context.add_global_context("PersistentDataHandleMap",
- &context.solve_context().handle_map());
+class SetParticleAttributeAction : public ParticleAction {
+ private:
+ std::string attribute_name_;
+ const CPPType &cpp_type_;
+ const ParticleFunction &inputs_fn_;
- fn::MFParamsBuilder mf_params{inputs_fn_, 1};
- bke::PersistentObjectHandle object_handle;
- float rate;
- mf_params.add_uninitialized_single_output(&object_handle);
- mf_params.add_uninitialized_single_output(&rate);
- inputs_fn_.call(IndexRange(1), mf_params, mf_context);
+ public:
+ SetParticleAttributeAction(std::string attribute_name,
+ const CPPType &cpp_type,
+ const ParticleFunction &inputs_fn)
+ : attribute_name_(std::move(attribute_name)), cpp_type_(cpp_type), inputs_fn_(inputs_fn)
+ {
+ }
- const Object *object = context.solve_context().handle_map().lookup(object_handle);
- if (object == nullptr) {
+ void execute(ParticleActionContext &context) const override
+ {
+ std::optional<GMutableSpan> attribute_array = context.particles.attributes.try_get(
+ attribute_name_, cpp_type_);
+ if (!attribute_array.has_value()) {
return;
}
- Vector<float3> new_positions;
- Vector<float3> new_velocities;
- Vector<float> new_birth_times;
-
- TimeInterval time_interval = context.simulation_time_interval();
- float start_time = time_interval.start();
- RandomNumberGenerator rng{(*(uint32_t *)&start_time) ^ seed_};
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ GVSpan values = evaluator.get(0);
- const float time_between_particles = 1.0f / rate;
- while (state->last_birth_time + time_between_particles < time_interval.end()) {
- new_positions.append(rng.get_unit_float3() * 0.3 + float3(object->loc));
- new_velocities.append(rng.get_unit_float3());
- const float birth_time = state->last_birth_time + time_between_particles;
- new_birth_times.append(birth_time);
- state->last_birth_time = birth_time;
+ if (values.is_single_element()) {
+ cpp_type_.fill_initialized_indices(
+ values.as_single_element(), attribute_array->data(), context.particles.index_mask);
+ }
+ else {
+ GSpan value_array = values.as_full_array();
+ cpp_type_.copy_to_initialized_indices(
+ value_array.data(), attribute_array->data(), context.particles.index_mask);
}
- for (StringRef name : names_) {
- ParticleAllocator *allocator = context.try_get_particle_allocator(name);
- if (allocator == nullptr) {
- return;
- }
-
- int amount = new_positions.size();
- fn::MutableAttributesRef attributes = allocator->allocate(amount);
-
- initialized_copy_n(new_positions.data(), amount, attributes.get<float3>("Position").data());
- initialized_copy_n(new_velocities.data(), amount, attributes.get<float3>("Velocity").data());
- initialized_copy_n(
- new_birth_times.data(), amount, attributes.get<float>("Birth Time").data());
+ if (attribute_name_ == "Velocity") {
+ context.particles.update_diffs_after_velocity_change();
}
}
};
-static Vector<const nodes::DNode *> find_linked_particle_simulations(
- const nodes::DOutputSocket &output_socket)
+static const ParticleAction *concatenate_actions(CollectContext &context,
+ Span<const ParticleAction *> actions)
{
- Vector<const nodes::DNode *> simulation_nodes;
- for (const nodes::DInputSocket *target_socket : output_socket.linked_sockets()) {
- if (target_socket->node().idname() == "SimulationNodeParticleSimulation") {
- simulation_nodes.append(&target_socket->node());
+ Vector<const ParticleAction *> non_null_actions;
+ for (const ParticleAction *action : actions) {
+ if (action != nullptr) {
+ non_null_actions.append(action);
}
}
- return simulation_nodes;
+ if (non_null_actions.size() == 0) {
+ return nullptr;
+ }
+ if (non_null_actions.size() == 1) {
+ return non_null_actions[0];
+ }
+ return &context.resources.construct<SequenceParticleAction>(AT, std::move(non_null_actions));
}
-static ParticleEmitter *create_particle_emitter(const nodes::DNode &dnode,
- ResourceCollector &resources,
- nodes::MFNetworkTreeMap &network_map,
- RequiredStates &r_required_states)
+static const ParticleAction *create_set_particle_attribute_action(
+ CollectContext &context, const DOutputSocket &dsocket, Span<StringRefNull> particle_names)
{
- Vector<const nodes::DNode *> simulation_dnodes = find_linked_particle_simulations(
- dnode.output(0));
- if (simulation_dnodes.size() == 0) {
- return nullptr;
+ const DNode &dnode = dsocket.node();
+
+ const ParticleAction *previous_action = create_particle_action(
+ context, dnode.input(0), particle_names);
+
+ MFInputSocket &name_socket = context.network_map.lookup_dummy(dnode.input(1));
+ MFInputSocket &value_socket = name_socket.node().input(1);
+ std::optional<Array<std::string>> names = compute_global_string_inputs(context.network_map,
+ {&name_socket});
+ if (!names.has_value()) {
+ return previous_action;
}
- Array<std::string> names{simulation_dnodes.size()};
- for (int i : simulation_dnodes.index_range()) {
- names[i] = dnode_to_path(*simulation_dnodes[i]);
+ std::string attribute_name = (*names)[0];
+ if (attribute_name.empty()) {
+ return previous_action;
}
+ const CPPType &attribute_type = value_socket.data_type().single_type();
- Array<const fn::MFInputSocket *> input_sockets{dnode.inputs().size()};
- for (int i : input_sockets.index_range()) {
- input_sockets[i] = &network_map.lookup_dummy(dnode.input(i));
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context,
+ {&value_socket});
+ if (inputs_fn == nullptr) {
+ return previous_action;
}
- if (network_map.network().have_dummy_or_unlinked_dependencies(input_sockets)) {
- return nullptr;
+ for (StringRef particle_name : particle_names) {
+ context.influences.particle_attributes_builder.lookup_as(particle_name)
+ ->add(attribute_name, attribute_type);
}
- fn::MultiFunction &inputs_fn = resources.construct<fn::MFNetworkEvaluator>(
- AT, Span<const fn::MFOutputSocket *>(), input_sockets.as_span());
+ ParticleAction &this_action = context.resources.construct<SetParticleAttributeAction>(
+ AT, attribute_name, attribute_type, *inputs_fn);
- std::string my_state_name = dnode_to_path(dnode);
- r_required_states.add(my_state_name, SIM_TYPE_NAME_PARTICLE_MESH_EMITTER);
- uint32_t seed = DefaultHash<std::string>{}(my_state_name);
- ParticleEmitter &emitter = resources.construct<MyBasicEmitter>(
- AT, std::move(names), std::move(my_state_name), inputs_fn, seed);
- return &emitter;
+ return concatenate_actions(context, {previous_action, &this_action});
}
-static void collect_emitters(nodes::MFNetworkTreeMap &network_map,
- ResourceCollector &resources,
- SimulationInfluences &r_influences,
- RequiredStates &r_required_states)
+class ParticleConditionAction : public ParticleAction {
+ private:
+ const ParticleFunction &inputs_fn_;
+ const ParticleAction *action_true_;
+ const ParticleAction *action_false_;
+
+ public:
+ ParticleConditionAction(const ParticleFunction &inputs_fn,
+ const ParticleAction *action_true,
+ const ParticleAction *action_false)
+ : inputs_fn_(inputs_fn), action_true_(action_true), action_false_(action_false)
+ {
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ VSpan<bool> conditions = evaluator.get<bool>(0, "Condition");
+
+ if (conditions.is_single_element()) {
+ const bool condition = conditions.as_single_element();
+ if (condition) {
+ if (action_true_ != nullptr) {
+ action_true_->execute(context);
+ }
+ }
+ else {
+ if (action_false_ != nullptr) {
+ action_false_->execute(context);
+ }
+ }
+ }
+ else {
+ Span<bool> conditions_array = conditions.as_full_array();
+
+ Vector<int64_t> true_indices;
+ Vector<int64_t> false_indices;
+ for (int i : context.particles.index_mask) {
+ if (conditions_array[i]) {
+ true_indices.append(i);
+ }
+ else {
+ false_indices.append(i);
+ }
+ }
+
+ if (action_true_ != nullptr) {
+ ParticleChunkContext chunk_context{context.particles.state,
+ true_indices.as_span(),
+ context.particles.attributes,
+ context.particles.integration};
+ ParticleActionContext action_context{context.solve_context, chunk_context};
+ action_true_->execute(action_context);
+ }
+ if (action_false_ != nullptr) {
+ ParticleChunkContext chunk_context{context.particles.state,
+ false_indices.as_span(),
+ context.particles.attributes,
+ context.particles.integration};
+ ParticleActionContext action_context{context.solve_context, chunk_context};
+ action_false_->execute(action_context);
+ }
+ }
+ }
+};
+
+static const ParticleAction *create_particle_condition_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names)
{
- for (const nodes::DNode *dnode :
- network_map.tree().nodes_by_type("SimulationNodeParticleMeshEmitter")) {
- ParticleEmitter *emitter = create_particle_emitter(
- *dnode, resources, network_map, r_required_states);
- if (emitter != nullptr) {
- r_influences.particle_emitters.append(emitter);
+ const DNode &dnode = dsocket.node();
+
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(
+ context, {&dnode.input(0, "Condition")});
+ if (inputs_fn == nullptr) {
+ return nullptr;
+ }
+
+ const ParticleAction *true_action = create_particle_action(
+ context, dnode.input(1), particle_names);
+ const ParticleAction *false_action = create_particle_action(
+ context, dnode.input(2), particle_names);
+
+ if (true_action == nullptr && false_action == nullptr) {
+ return nullptr;
+ }
+ return &context.resources.construct<ParticleConditionAction>(
+ AT, *inputs_fn, true_action, false_action);
+}
+
+class KillParticleAction : public ParticleAction {
+ public:
+ void execute(ParticleActionContext &context) const override
+ {
+ MutableSpan<int> dead_states = context.particles.attributes.get<int>("Dead");
+ for (int i : context.particles.index_mask) {
+ dead_states[i] = true;
}
}
+};
+
+static const ParticleAction *create_particle_action(CollectContext &context,
+ const DOutputSocket &dsocket,
+ Span<StringRefNull> particle_names)
+{
+ const DNode &dnode = dsocket.node();
+ StringRef idname = dnode.idname();
+ if (idname == "SimulationNodeSetParticleAttribute") {
+ return create_set_particle_attribute_action(context, dsocket, particle_names);
+ }
+ if (idname == "SimulationNodeExecuteCondition") {
+ return create_particle_condition_action(context, dsocket, particle_names);
+ }
+ if (idname == "SimulationNodeKillParticle") {
+ return &context.resources.construct<KillParticleAction>(AT);
+ }
+ return nullptr;
}
-static void prepare_particle_attribute_builders(nodes::MFNetworkTreeMap &network_map,
- ResourceCollector &resources,
- SimulationInfluences &r_influences)
+static void initialize_particle_attribute_builders(CollectContext &context)
{
- for (const nodes::DNode *dnode : get_particle_simulation_nodes(network_map.tree())) {
- std::string name = dnode_to_path(*dnode);
- fn::AttributesInfoBuilder &builder = resources.construct<fn::AttributesInfoBuilder>(AT);
- builder.add<float3>("Position", {0, 0, 0});
- builder.add<float3>("Velocity", {0, 0, 0});
- builder.add<int>("ID", 0);
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ StringRef name = get_identifier(context, *dnode);
+ AttributesInfoBuilder &attributes_builder = context.resources.construct<AttributesInfoBuilder>(
+ AT);
+ attributes_builder.add<float3>("Position", {0, 0, 0});
+ attributes_builder.add<float3>("Velocity", {0, 0, 0});
+ attributes_builder.add<int>("ID", 0);
/* TODO: Use bool property, but need to add CD_PROP_BOOL first. */
- builder.add<int>("Dead", 0);
- builder.add<float>("Birth Time", 0.0f);
- r_influences.particle_attributes_builder.add_new(std::move(name), &builder);
+ attributes_builder.add<int>("Dead", 0);
+ /* TODO: Use uint32_t, but we don't have a corresponding custom property type. */
+ attributes_builder.add<int>("Hash", 0);
+ attributes_builder.add<float>("Birth Time", 0.0f);
+ attributes_builder.add<float>("Radius", 0.02f);
+ context.influences.particle_attributes_builder.add_new(name, &attributes_builder);
}
}
-static void find_used_data_blocks(const nodes::DerivedNodeTree &tree,
- SimulationInfluences &r_influences)
+static void optimize_function_network(CollectContext &context)
+{
+ fn::mf_network_optimization::constant_folding(context.network, context.resources);
+ fn::mf_network_optimization::common_subnetwork_elimination(context.network);
+ fn::mf_network_optimization::dead_node_removal(context.network);
+ // WM_clipboard_text_set(network.to_dot().c_str(), false);
+}
+
+class AgeReachedEvent : public ParticleEvent {
+ private:
+ std::string attribute_name_;
+ const ParticleFunction &inputs_fn_;
+ const ParticleAction &action_;
+
+ public:
+ AgeReachedEvent(std::string attribute_name,
+ const ParticleFunction &inputs_fn,
+ const ParticleAction &action)
+ : attribute_name_(std::move(attribute_name)), inputs_fn_(inputs_fn), action_(action)
+ {
+ }
+
+ void filter(ParticleEventFilterContext &context) const override
+ {
+ Span<float> birth_times = context.particles.attributes.get<float>("Birth Time");
+ std::optional<Span<int>> has_been_triggered = context.particles.attributes.try_get<int>(
+ attribute_name_);
+ if (!has_been_triggered.has_value()) {
+ return;
+ }
+
+ ParticleFunctionEvaluator evaluator{inputs_fn_, context.solve_context, context.particles};
+ evaluator.compute();
+ VSpan<float> trigger_ages = evaluator.get<float>(0, "Age");
+
+ const float end_time = context.particles.integration->end_time;
+ for (int i : context.particles.index_mask) {
+ if ((*has_been_triggered)[i]) {
+ continue;
+ }
+ const float trigger_age = trigger_ages[i];
+ const float birth_time = birth_times[i];
+ const float trigger_time = birth_time + trigger_age;
+ if (trigger_time > end_time) {
+ continue;
+ }
+
+ const float duration = context.particles.integration->durations[i];
+ TimeInterval interval(end_time - duration, duration);
+ const float time_factor = interval.safe_factor_at_time(trigger_time);
+
+ context.factor_dst[i] = std::max<float>(0.0f, time_factor);
+ }
+ }
+
+ void execute(ParticleActionContext &context) const override
+ {
+ MutableSpan<int> has_been_triggered = context.particles.attributes.get<int>(attribute_name_);
+ for (int i : context.particles.index_mask) {
+ has_been_triggered[i] = 1;
+ }
+ action_.execute(context);
+ }
+};
+
+static void collect_age_reached_events(CollectContext &context)
{
- const bNodeSocketType *socktype = nodeSocketTypeFind("NodeSocketObject");
- BLI_assert(socktype != nullptr);
-
- for (const nodes::DInputSocket *dsocket : tree.input_sockets()) {
- const bNodeSocket *bsocket = dsocket->bsocket();
- if (bsocket->typeinfo == socktype) {
- Object *value = ((const bNodeSocketValueObject *)bsocket->default_value)->value;
- if (value != nullptr) {
- r_influences.used_data_blocks.add(&value->id);
+ for (const DNode *dnode : nodes_by_type(context, "SimulationNodeAgeReachedEvent")) {
+ const DInputSocket &age_input = dnode->input(0, "Age");
+ const DInputSocket &execute_input = dnode->input(1, "Execute");
+ Array<StringRefNull> particle_names = find_linked_particle_simulations(context,
+ dnode->output(0));
+ const ParticleAction *action = create_particle_action(context, execute_input, particle_names);
+ if (action == nullptr) {
+ continue;
+ }
+ const ParticleFunction *inputs_fn = create_particle_function_for_inputs(context, {&age_input});
+ if (inputs_fn == nullptr) {
+ continue;
+ }
+
+ std::string attribute_name = get_identifier(context, *dnode);
+ const ParticleEvent &event = context.resources.construct<AgeReachedEvent>(
+ AT, attribute_name, *inputs_fn, *action);
+ for (StringRefNull particle_name : particle_names) {
+ const bool added_attribute = context.influences.particle_attributes_builder
+ .lookup_as(particle_name)
+ ->add<int>(attribute_name, 0);
+ if (added_attribute) {
+ context.influences.particle_events.add_as(particle_name, &event);
}
}
}
@@ -456,30 +879,29 @@ void collect_simulation_influences(Simulation &simulation,
SimulationInfluences &r_influences,
RequiredStates &r_required_states)
{
- nodes::NodeTreeRefMap tree_refs;
- const nodes::DerivedNodeTree tree{simulation.nodetree, tree_refs};
+ NodeTreeRefMap tree_refs;
+ const DerivedNodeTree tree{simulation.nodetree, tree_refs};
- fn::MFNetwork &network = resources.construct<fn::MFNetwork>(AT);
- nodes::MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
+ MFNetwork &network = resources.construct<MFNetwork>(AT);
+ MFNetworkTreeMap network_map = insert_node_tree_into_mf_network(network, tree, resources);
- prepare_particle_attribute_builders(network_map, resources, r_influences);
+ CollectContext context{r_influences, r_required_states, resources, network_map};
+ initialize_particle_attribute_builders(context);
- DummyDataSources data_sources;
- find_and_deduplicate_particle_attribute_nodes(network_map, data_sources);
+ prepare_particle_attribute_nodes(context);
+ prepare_time_input_nodes(context);
- fn::mf_network_optimization::constant_folding(network, resources);
- fn::mf_network_optimization::common_subnetwork_elimination(network);
- fn::mf_network_optimization::dead_node_removal(network);
- // WM_clipboard_text_set(network.to_dot().c_str(), false);
+ collect_forces(context);
+ collect_emitters(context);
+ collect_birth_events(context);
+ collect_time_step_events(context);
+ collect_age_reached_events(context);
- collect_forces(network_map, resources, data_sources, r_influences);
- collect_emitters(network_map, resources, r_influences, r_required_states);
+ optimize_function_network(context);
- for (const nodes::DNode *dnode : get_particle_simulation_nodes(tree)) {
- r_required_states.add(dnode_to_path(*dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION);
+ for (const DNode *dnode : context.particle_simulation_nodes) {
+ r_required_states.add(get_identifier(context, *dnode), SIM_TYPE_NAME_PARTICLE_SIMULATION);
}
-
- find_used_data_blocks(tree, r_influences);
}
} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_collect_influences.hh b/source/blender/simulation/intern/simulation_collect_influences.hh
index 5035461191e..8673a308b04 100644
--- a/source/blender/simulation/intern/simulation_collect_influences.hh
+++ b/source/blender/simulation/intern/simulation_collect_influences.hh
@@ -20,7 +20,7 @@
#include "BLI_resource_collector.hh"
-#include "simulation_solver.hh"
+#include "simulation_solver_influences.hh"
namespace blender::sim {
diff --git a/source/blender/simulation/intern/simulation_solver.cc b/source/blender/simulation/intern/simulation_solver.cc
index ee7a8d40035..d53ccd2bd49 100644
--- a/source/blender/simulation/intern/simulation_solver.cc
+++ b/source/blender/simulation/intern/simulation_solver.cc
@@ -17,23 +17,16 @@
#include "simulation_solver.hh"
#include "BKE_customdata.h"
-#include "BKE_lib_id.h"
#include "BKE_persistent_data_handle.hh"
#include "BLI_rand.hh"
#include "BLI_set.hh"
-namespace blender::sim {
-
-ParticleForce::~ParticleForce()
-{
-}
+#include "DEG_depsgraph_query.h"
-ParticleEmitter::~ParticleEmitter()
-{
-}
+namespace blender::sim {
-static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type)
+static CustomDataType cpp_to_custom_data_type(const CPPType &type)
{
if (type.is<float3>()) {
return CD_PROP_FLOAT3;
@@ -48,18 +41,18 @@ static CustomDataType cpp_to_custom_data_type(const fn::CPPType &type)
return CD_PROP_FLOAT;
}
-static const fn::CPPType &custom_to_cpp_data_type(CustomDataType type)
+static const CPPType &custom_to_cpp_data_type(CustomDataType type)
{
switch (type) {
case CD_PROP_FLOAT3:
- return fn::CPPType::get<float3>();
+ return CPPType::get<float3>();
case CD_PROP_FLOAT:
- return fn::CPPType::get<float>();
+ return CPPType::get<float>();
case CD_PROP_INT32:
- return fn::CPPType::get<int32_t>();
+ return CPPType::get<int32_t>();
default:
BLI_assert(false);
- return fn::CPPType::get<float>();
+ return CPPType::get<float>();
}
}
@@ -67,33 +60,33 @@ class CustomDataAttributesRef {
private:
Array<void *> buffers_;
int64_t size_;
- const fn::AttributesInfo &info_;
+ const AttributesInfo &info_;
public:
- CustomDataAttributesRef(CustomData &custom_data, int64_t size, const fn::AttributesInfo &info)
+ CustomDataAttributesRef(CustomData &custom_data, int64_t size, const AttributesInfo &info)
: buffers_(info.size(), nullptr), size_(size), info_(info)
{
for (int attribute_index : info.index_range()) {
StringRefNull name = info.name_of(attribute_index);
- const fn::CPPType &cpp_type = info.type_of(attribute_index);
+ const CPPType &cpp_type = info.type_of(attribute_index);
CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
void *data = CustomData_get_layer_named(&custom_data, custom_type, name.c_str());
buffers_[attribute_index] = data;
}
}
- operator fn::MutableAttributesRef()
+ operator MutableAttributesRef()
{
- return fn::MutableAttributesRef(info_, buffers_, size_);
+ return MutableAttributesRef(info_, buffers_, size_);
}
- operator fn::AttributesRef() const
+ operator AttributesRef() const
{
- return fn::AttributesRef(info_, buffers_, size_);
+ return AttributesRef(info_, buffers_, size_);
}
};
-static void ensure_attributes_exist(ParticleSimulationState *state, const fn::AttributesInfo &info)
+static void ensure_attributes_exist(ParticleSimulationState *state, const AttributesInfo &info)
{
bool found_layer_to_remove;
do {
@@ -101,7 +94,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
for (int layer_index = 0; layer_index < state->attributes.totlayer; layer_index++) {
CustomDataLayer *layer = &state->attributes.layers[layer_index];
BLI_assert(layer->name != nullptr);
- const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type);
+ const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer->type);
StringRefNull name = layer->name;
if (!info.has_attribute(name, cpp_type)) {
found_layer_to_remove = true;
@@ -113,7 +106,7 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
for (int attribute_index : info.index_range()) {
StringRefNull attribute_name = info.name_of(attribute_index);
- const fn::CPPType &cpp_type = info.type_of(attribute_index);
+ const CPPType &cpp_type = info.type_of(attribute_index);
CustomDataType custom_type = cpp_to_custom_data_type(cpp_type);
if (CustomData_get_layer_named(&state->attributes, custom_type, attribute_name.c_str()) ==
nullptr) {
@@ -128,50 +121,241 @@ static void ensure_attributes_exist(ParticleSimulationState *state, const fn::At
}
}
-BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
- ParticleSimulationState &state,
- const fn::AttributesInfo &attributes_info)
+BLI_NOINLINE static void apply_remaining_diffs(ParticleChunkContext &context)
{
- CustomDataAttributesRef custom_data_attributes{
- state.attributes, state.tot_particles, attributes_info};
- fn::MutableAttributesRef attributes = custom_data_attributes;
+ BLI_assert(context.integration != nullptr);
+ MutableSpan<float3> positions = context.attributes.get<float3>("Position");
+ MutableSpan<float3> velocities = context.attributes.get<float3>("Velocity");
+
+ for (int i : context.index_mask) {
+ positions[i] += context.integration->position_diffs[i];
+ velocities[i] += context.integration->velocity_diffs[i];
+ }
+}
- Array<float3> force_vectors{state.tot_particles, {0, 0, 0}};
- const Vector<const ParticleForce *> *forces =
- solve_context.influences().particle_forces.lookup_ptr(state.head.name);
+BLI_NOINLINE static void find_next_event_per_particle(
+ SimulationSolveContext &solve_context,
+ ParticleChunkContext &particles,
+ Span<const ParticleEvent *> events,
+ MutableSpan<int> r_next_event_indices,
+ MutableSpan<float> r_time_factors_to_next_event)
+{
+ r_next_event_indices.fill_indices(particles.index_mask, -1);
+ r_time_factors_to_next_event.fill_indices(particles.index_mask, 1.0f);
+
+ Array<float> time_factors(particles.index_mask.min_array_size());
+ for (int event_index : events.index_range()) {
+ time_factors.fill(-1.0f);
+ ParticleEventFilterContext event_context{solve_context, particles, time_factors};
+ const ParticleEvent &event = *events[event_index];
+ event.filter(event_context);
+
+ for (int i : particles.index_mask) {
+ const float time_factor = time_factors[i];
+ const float previously_smallest_time_factor = r_time_factors_to_next_event[i];
+ if (time_factor >= 0.0f && time_factor <= previously_smallest_time_factor) {
+ r_time_factors_to_next_event[i] = time_factor;
+ r_next_event_indices[i] = event_index;
+ }
+ }
+ }
+}
- if (forces != nullptr) {
- ParticleChunkContext particle_chunk_context{IndexMask(state.tot_particles), attributes};
- ParticleForceContext particle_force_context{
- solve_context, particle_chunk_context, force_vectors};
+BLI_NOINLINE static void forward_particles_to_next_event_or_end(
+ ParticleChunkContext &particles, Span<float> time_factors_to_next_event)
+{
+ MutableSpan<float3> positions = particles.attributes.get<float3>("Position");
+ MutableSpan<float3> velocities = particles.attributes.get<float3>("Velocity");
+
+ MutableSpan<float3> position_diffs = particles.integration->position_diffs;
+ MutableSpan<float3> velocity_diffs = particles.integration->velocity_diffs;
+ MutableSpan<float> durations = particles.integration->durations;
+
+ for (int i : particles.index_mask) {
+ const float time_factor = time_factors_to_next_event[i];
+ positions[i] += position_diffs[i] * time_factor;
+ velocities[i] += velocity_diffs[i] * time_factor;
+
+ const float remaining_time_factor = 1.0f - time_factor;
+ position_diffs[i] *= remaining_time_factor;
+ velocity_diffs[i] *= remaining_time_factor;
+ durations[i] *= remaining_time_factor;
+ }
+}
- for (const ParticleForce *force : *forces) {
- force->add_force(particle_force_context);
+BLI_NOINLINE static void group_particles_by_event(
+ IndexMask mask,
+ Span<int> next_event_indices,
+ MutableSpan<Vector<int64_t>> r_particles_per_event)
+{
+ for (int i : mask) {
+ int event_index = next_event_indices[i];
+ if (event_index >= 0) {
+ r_particles_per_event[event_index].append(i);
}
}
+}
- MutableSpan<float3> positions = attributes.get<float3>("Position");
- MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
- MutableSpan<float> birth_times = attributes.get<float>("Birth Time");
- MutableSpan<int> dead_states = attributes.get<int>("Dead");
- float end_time = solve_context.solve_interval().end();
- float time_step = solve_context.solve_interval().duration();
- for (int i : positions.index_range()) {
- velocities[i] += force_vectors[i] * time_step;
- positions[i] += velocities[i] * time_step;
-
- if (end_time - birth_times[i] > 2) {
- dead_states[i] = true;
+BLI_NOINLINE static void execute_events(SimulationSolveContext &solve_context,
+ ParticleChunkContext &all_particles,
+ Span<const ParticleEvent *> events,
+ Span<Vector<int64_t>> particles_per_event)
+{
+ for (int event_index : events.index_range()) {
+ Span<int64_t> pindices = particles_per_event[event_index];
+ if (pindices.is_empty()) {
+ continue;
+ }
+
+ const ParticleEvent &event = *events[event_index];
+ ParticleChunkContext particles{
+ all_particles.state, pindices, all_particles.attributes, all_particles.integration};
+ ParticleActionContext action_context{solve_context, particles};
+ event.execute(action_context);
+ }
+}
+
+BLI_NOINLINE static void find_unfinished_particles(IndexMask index_mask,
+ Span<float> time_factors_to_next_event,
+ Vector<int64_t> &r_unfinished_pindices)
+{
+ for (int i : index_mask) {
+ float time_factor = time_factors_to_next_event[i];
+ if (time_factor < 1.0f) {
+ r_unfinished_pindices.append(i);
+ }
+ }
+}
+
+BLI_NOINLINE static void simulate_to_next_event(SimulationSolveContext &solve_context,
+ ParticleChunkContext &particles,
+ Span<const ParticleEvent *> events,
+ Vector<int64_t> &r_unfinished_pindices)
+{
+ int array_size = particles.index_mask.min_array_size();
+ Array<int> next_event_indices(array_size);
+ Array<float> time_factors_to_next_event(array_size);
+
+ find_next_event_per_particle(
+ solve_context, particles, events, next_event_indices, time_factors_to_next_event);
+
+ forward_particles_to_next_event_or_end(particles, time_factors_to_next_event);
+
+ Array<Vector<int64_t>> particles_per_event(events.size());
+ group_particles_by_event(particles.index_mask, next_event_indices, particles_per_event);
+
+ execute_events(solve_context, particles, events, particles_per_event);
+ find_unfinished_particles(
+ particles.index_mask, time_factors_to_next_event, r_unfinished_pindices);
+}
+
+BLI_NOINLINE static void simulate_with_max_n_events(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ ParticleChunkContext &particles,
+ int max_events)
+{
+ Span<const ParticleEvent *> events = solve_context.influences.particle_events.lookup_as(
+ state.head.name);
+ if (events.size() == 0) {
+ apply_remaining_diffs(particles);
+ return;
+ }
+
+ Vector<int64_t> unfininished_pindices = particles.index_mask.indices();
+ for (int iteration : IndexRange(max_events)) {
+ UNUSED_VARS(iteration);
+ if (unfininished_pindices.is_empty()) {
+ break;
}
+
+ Vector<int64_t> new_unfinished_pindices;
+ ParticleChunkContext remaining_particles{particles.state,
+ unfininished_pindices.as_span(),
+ particles.attributes,
+ particles.integration};
+ simulate_to_next_event(solve_context, remaining_particles, events, new_unfinished_pindices);
+ unfininished_pindices = std::move(new_unfinished_pindices);
+ }
+
+ if (!unfininished_pindices.is_empty()) {
+ ParticleChunkContext remaining_particles{particles.state,
+ unfininished_pindices.as_span(),
+ particles.attributes,
+ particles.integration};
+ apply_remaining_diffs(remaining_particles);
}
}
+BLI_NOINLINE static void simulate_particle_chunk(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ MutableAttributesRef attributes,
+ MutableSpan<float> remaining_durations,
+ float end_time)
+{
+ int particle_amount = attributes.size();
+
+ Span<const ParticleAction *> begin_actions =
+ solve_context.influences.particle_time_step_begin_actions.lookup_as(state.head.name);
+ for (const ParticleAction *action : begin_actions) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleActionContext action_context{solve_context, particles};
+ action->execute(action_context);
+ }
+
+ Array<float3> force_vectors{particle_amount, {0, 0, 0}};
+ Span<const ParticleForce *> forces = solve_context.influences.particle_forces.lookup_as(
+ state.head.name);
+ for (const ParticleForce *force : forces) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleForceContext particle_force_context{solve_context, particles, force_vectors};
+ force->add_force(particle_force_context);
+ }
+
+ MutableSpan<float3> velocities = attributes.get<float3>("Velocity");
+
+ Array<float3> position_diffs(particle_amount);
+ Array<float3> velocity_diffs(particle_amount);
+ for (int i : IndexRange(particle_amount)) {
+ const float time_step = remaining_durations[i];
+ velocity_diffs[i] = force_vectors[i] * time_step;
+ position_diffs[i] = (velocities[i] + velocity_diffs[i] / 2.0f) * time_step;
+ }
+
+ ParticleChunkIntegrationContext integration_context = {
+ position_diffs, velocity_diffs, remaining_durations, end_time};
+ ParticleChunkContext particle_chunk_context{
+ state, IndexMask(particle_amount), attributes, &integration_context};
+
+ simulate_with_max_n_events(solve_context, state, particle_chunk_context, 10);
+
+ Span<const ParticleAction *> end_actions =
+ solve_context.influences.particle_time_step_end_actions.lookup_as(state.head.name);
+ for (const ParticleAction *action : end_actions) {
+ ParticleChunkContext particles{state, IndexMask(particle_amount), attributes};
+ ParticleActionContext action_context{solve_context, particles};
+ action->execute(action_context);
+ }
+}
+
+BLI_NOINLINE static void simulate_existing_particles(SimulationSolveContext &solve_context,
+ ParticleSimulationState &state,
+ const AttributesInfo &attributes_info)
+{
+ CustomDataAttributesRef custom_data_attributes{
+ state.attributes, state.tot_particles, attributes_info};
+ MutableAttributesRef attributes = custom_data_attributes;
+
+ Array<float> remaining_durations(state.tot_particles, solve_context.solve_interval.duration());
+ simulate_particle_chunk(
+ solve_context, state, attributes, remaining_durations, solve_context.solve_interval.stop());
+}
+
BLI_NOINLINE static void run_emitters(SimulationSolveContext &solve_context,
ParticleAllocators &particle_allocators)
{
- for (const ParticleEmitter *emitter : solve_context.influences().particle_emitters) {
+ for (const ParticleEmitter *emitter : solve_context.influences.particle_emitters) {
ParticleEmitterContext emitter_context{
- solve_context, particle_allocators, solve_context.solve_interval()};
+ solve_context, particle_allocators, solve_context.solve_interval};
emitter->emit(emitter_context);
}
}
@@ -181,10 +365,10 @@ BLI_NOINLINE static int count_particles_after_time_step(ParticleSimulationState
{
CustomDataAttributesRef custom_data_attributes{
state.attributes, state.tot_particles, allocator.attributes_info()};
- fn::MutableAttributesRef attributes = custom_data_attributes;
+ MutableAttributesRef attributes = custom_data_attributes;
int new_particle_amount = attributes.get<int>("Dead").count(0);
- for (fn::MutableAttributesRef emitted_attributes : allocator.get_allocations()) {
+ for (MutableAttributesRef emitted_attributes : allocator.get_allocations()) {
new_particle_amount += emitted_attributes.get<int>("Dead").count(0);
}
@@ -199,7 +383,7 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta
CustomDataAttributesRef custom_data_attributes{
state.attributes, state.tot_particles, allocator.attributes_info()};
- Vector<fn::MutableAttributesRef> particle_sources;
+ Vector<MutableAttributesRef> particle_sources;
particle_sources.append(custom_data_attributes);
particle_sources.extend(allocator.get_allocations());
@@ -211,16 +395,16 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta
dead_layer = &layer;
continue;
}
- const fn::CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type);
- fn::GMutableSpan new_buffer{
+ const CPPType &cpp_type = custom_to_cpp_data_type((CustomDataType)layer.type);
+ GMutableSpan new_buffer{
cpp_type,
MEM_mallocN_aligned(new_particle_amount * cpp_type.size(), cpp_type.alignment(), AT),
new_particle_amount};
int current = 0;
- for (fn::MutableAttributesRef attributes : particle_sources) {
+ for (MutableAttributesRef attributes : particle_sources) {
Span<int> dead_states = attributes.get<int>("Dead");
- fn::GSpan source_buffer = attributes.get(name);
+ GSpan source_buffer = attributes.get(name);
BLI_assert(source_buffer.type() == cpp_type);
for (int i : attributes.index_range()) {
if (dead_states[i] == 0) {
@@ -233,7 +417,7 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta
if (layer.data != nullptr) {
MEM_freeN(layer.data);
}
- layer.data = new_buffer.buffer();
+ layer.data = new_buffer.data();
}
BLI_assert(dead_layer != nullptr);
@@ -246,56 +430,10 @@ BLI_NOINLINE static void remove_dead_and_add_new_particles(ParticleSimulationSta
state.next_particle_id += allocator.total_allocated();
}
-static void update_persistent_data_handles(Simulation &simulation,
- const VectorSet<ID *> &used_data_blocks)
-{
- Set<ID *> contained_ids;
- Set<int> used_handles;
-
- /* Remove handles that have been invalidated. */
- LISTBASE_FOREACH_MUTABLE (
- PersistentDataHandleItem *, handle_item, &simulation.persistent_data_handles) {
- if (handle_item->id == nullptr) {
- BLI_remlink(&simulation.persistent_data_handles, handle_item);
- continue;
- }
- if (!used_data_blocks.contains(handle_item->id)) {
- id_us_min(handle_item->id);
- BLI_remlink(&simulation.persistent_data_handles, handle_item);
- MEM_freeN(handle_item);
- continue;
- }
- contained_ids.add_new(handle_item->id);
- used_handles.add_new(handle_item->handle);
- }
-
- /* Add new handles that are not in the list yet. */
- int next_handle = 0;
- for (ID *id : used_data_blocks) {
- if (contained_ids.contains(id)) {
- continue;
- }
-
- /* Find the next available handle. */
- while (used_handles.contains(next_handle)) {
- next_handle++;
- }
- used_handles.add_new(next_handle);
-
- PersistentDataHandleItem *handle_item = (PersistentDataHandleItem *)MEM_callocN(
- sizeof(*handle_item), AT);
- /* Cannot store const pointers in DNA. */
- id_us_plus(id);
- handle_item->id = id;
- handle_item->handle = next_handle;
-
- BLI_addtail(&simulation.persistent_data_handles, handle_item);
- }
-}
-
void initialize_simulation_states(Simulation &simulation,
Depsgraph &UNUSED(depsgraph),
- const SimulationInfluences &UNUSED(influences))
+ const SimulationInfluences &UNUSED(influences),
+ const bke::PersistentDataHandleMap &UNUSED(handle_map))
{
simulation.current_simulation_time = 0.0f;
}
@@ -303,15 +441,10 @@ void initialize_simulation_states(Simulation &simulation,
void solve_simulation_time_step(Simulation &simulation,
Depsgraph &depsgraph,
const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map,
+ const DependencyAnimations &dependency_animations,
float time_step)
{
- update_persistent_data_handles(simulation, influences.used_data_blocks);
-
- bke::PersistentDataHandleMap handle_map;
- LISTBASE_FOREACH (PersistentDataHandleItem *, handle, &simulation.persistent_data_handles) {
- handle_map.add(handle->handle, *handle->id);
- }
-
SimulationStateMap state_map;
LISTBASE_FOREACH (SimulationState *, state, &simulation.states) {
state_map.add(state);
@@ -322,30 +455,32 @@ void solve_simulation_time_step(Simulation &simulation,
influences,
TimeInterval(simulation.current_simulation_time, time_step),
state_map,
- handle_map};
- TimeInterval simulation_time_interval{simulation.current_simulation_time, time_step};
+ handle_map,
+ dependency_animations};
Span<ParticleSimulationState *> particle_simulation_states =
state_map.lookup<ParticleSimulationState>();
- Map<std::string, std::unique_ptr<fn::AttributesInfo>> attribute_infos;
+ Map<std::string, std::unique_ptr<AttributesInfo>> attribute_infos;
Map<std::string, std::unique_ptr<ParticleAllocator>> particle_allocators_map;
for (ParticleSimulationState *state : particle_simulation_states) {
- const fn::AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as(
+ const AttributesInfoBuilder &builder = *influences.particle_attributes_builder.lookup_as(
state->head.name);
- auto info = std::make_unique<fn::AttributesInfo>(builder);
+ auto info = std::make_unique<AttributesInfo>(builder);
ensure_attributes_exist(state, *info);
+ uint32_t hash_seed = DefaultHash<StringRef>{}(state->head.name);
particle_allocators_map.add_new(
- state->head.name, std::make_unique<ParticleAllocator>(*info, state->next_particle_id));
+ state->head.name,
+ std::make_unique<ParticleAllocator>(*info, state->next_particle_id, hash_seed));
attribute_infos.add_new(state->head.name, std::move(info));
}
ParticleAllocators particle_allocators{particle_allocators_map};
for (ParticleSimulationState *state : particle_simulation_states) {
- const fn::AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
+ const AttributesInfo &attributes_info = *attribute_infos.lookup_as(state->head.name);
simulate_existing_particles(solve_context, *state, attributes_info);
}
@@ -353,10 +488,35 @@ void solve_simulation_time_step(Simulation &simulation,
for (ParticleSimulationState *state : particle_simulation_states) {
ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+
+ for (MutableAttributesRef attributes : allocator.get_allocations()) {
+ Span<const ParticleAction *> actions = influences.particle_birth_actions.lookup_as(
+ state->head.name);
+ for (const ParticleAction *action : actions) {
+ ParticleChunkContext chunk_context{*state, IndexRange(attributes.size()), attributes};
+ ParticleActionContext action_context{solve_context, chunk_context};
+ action->execute(action_context);
+ }
+ }
+ }
+
+ for (ParticleSimulationState *state : particle_simulation_states) {
+ ParticleAllocator &allocator = *particle_allocators.try_get_allocator(state->head.name);
+
+ for (MutableAttributesRef attributes : allocator.get_allocations()) {
+ Array<float> remaining_durations(attributes.size());
+ Span<float> birth_times = attributes.get<float>("Birth Time");
+ const float end_time = solve_context.solve_interval.stop();
+ for (int i : attributes.index_range()) {
+ remaining_durations[i] = end_time - birth_times[i];
+ }
+ simulate_particle_chunk(solve_context, *state, attributes, remaining_durations, end_time);
+ }
+
remove_dead_and_add_new_particles(*state, allocator);
}
- simulation.current_simulation_time = simulation_time_interval.end();
+ simulation.current_simulation_time = solve_context.solve_interval.stop();
}
} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver.hh b/source/blender/simulation/intern/simulation_solver.hh
index 3fc61f579e3..2cf8eb2aa27 100644
--- a/source/blender/simulation/intern/simulation_solver.hh
+++ b/source/blender/simulation/intern/simulation_solver.hh
@@ -16,259 +16,22 @@
#pragma once
-#include "BLI_float3.hh"
-#include "BLI_span.hh"
-
-#include "DNA_simulation_types.h"
-
-#include "FN_attributes_ref.hh"
-
-#include "BKE_persistent_data_handle.hh"
-#include "BKE_simulation.h"
-
-#include "particle_allocator.hh"
-#include "time_interval.hh"
+#include "simulation_collect_influences.hh"
struct Depsgraph;
namespace blender::sim {
-class ParticleEmitterContext;
-class ParticleForceContext;
-
-class ParticleEmitter {
- public:
- virtual ~ParticleEmitter();
- virtual void emit(ParticleEmitterContext &context) const = 0;
-};
-
-class ParticleForce {
- public:
- virtual ~ParticleForce();
- virtual void add_force(ParticleForceContext &context) const = 0;
-};
-
-struct SimulationInfluences {
- Map<std::string, Vector<const ParticleForce *>> particle_forces;
- Map<std::string, fn::AttributesInfoBuilder *> particle_attributes_builder;
- Vector<const ParticleEmitter *> particle_emitters;
- VectorSet<ID *> used_data_blocks;
-};
-
-class SimulationStateMap {
- private:
- Map<StringRefNull, SimulationState *> states_by_name_;
- Map<StringRefNull, Vector<SimulationState *>> states_by_type_;
-
- public:
- void add(SimulationState *state)
- {
- states_by_name_.add_new(state->name, state);
- states_by_type_.lookup_or_add_default(state->type).append(state);
- }
-
- template<typename StateType> StateType *lookup(StringRef name) const
- {
- const char *type = BKE_simulation_get_state_type_name<StateType>();
- return (StateType *)this->lookup_name_type(name, type);
- }
-
- template<typename StateType> Span<StateType *> lookup() const
- {
- const char *type = BKE_simulation_get_state_type_name<StateType>();
- return this->lookup_type(type).cast<StateType *>();
- }
-
- SimulationState *lookup_name_type(StringRef name, StringRef type) const
- {
- SimulationState *state = states_by_name_.lookup_default_as(name, nullptr);
- if (state == nullptr) {
- return nullptr;
- }
- if (state->type == type) {
- return state;
- }
- return nullptr;
- }
-
- Span<SimulationState *> lookup_type(StringRef type) const
- {
- const Vector<SimulationState *> *states = states_by_type_.lookup_ptr_as(type);
- if (states == nullptr) {
- return {};
- }
- else {
- return states->as_span();
- }
- }
-};
-
-class SimulationSolveContext {
- private:
- Simulation &simulation_;
- Depsgraph &depsgraph_;
- const SimulationInfluences &influences_;
- TimeInterval solve_interval_;
- const SimulationStateMap &state_map_;
- const bke::PersistentDataHandleMap &id_handle_map_;
-
- public:
- SimulationSolveContext(Simulation &simulation,
- Depsgraph &depsgraph,
- const SimulationInfluences &influences,
- TimeInterval solve_interval,
- const SimulationStateMap &state_map,
- const bke::PersistentDataHandleMap &handle_map)
- : simulation_(simulation),
- depsgraph_(depsgraph),
- influences_(influences),
- solve_interval_(solve_interval),
- state_map_(state_map),
- id_handle_map_(handle_map)
- {
- }
-
- TimeInterval solve_interval() const
- {
- return solve_interval_;
- }
-
- const SimulationInfluences &influences() const
- {
- return influences_;
- }
-
- const bke::PersistentDataHandleMap &handle_map() const
- {
- return id_handle_map_;
- }
-
- const SimulationStateMap &state_map() const
- {
- return state_map_;
- }
-};
-
-class ParticleAllocators {
- private:
- Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_;
-
- public:
- ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators)
- : allocators_(allocators)
- {
- }
-
- ParticleAllocator *try_get_allocator(StringRef particle_simulation_name)
- {
- auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name);
- if (ptr != nullptr) {
- return ptr->get();
- }
- else {
- return nullptr;
- }
- }
-};
-
-class ParticleChunkContext {
- private:
- IndexMask index_mask_;
- fn::MutableAttributesRef attributes_;
-
- public:
- ParticleChunkContext(IndexMask index_mask, fn::MutableAttributesRef attributes)
- : index_mask_(index_mask), attributes_(attributes)
- {
- }
-
- IndexMask index_mask() const
- {
- return index_mask_;
- }
-
- fn::MutableAttributesRef attributes()
- {
- return attributes_;
- }
-
- fn::AttributesRef attributes() const
- {
- return attributes_;
- }
-};
-
-class ParticleEmitterContext {
- private:
- SimulationSolveContext &solve_context_;
- ParticleAllocators &particle_allocators_;
- TimeInterval simulation_time_interval_;
-
- public:
- ParticleEmitterContext(SimulationSolveContext &solve_context,
- ParticleAllocators &particle_allocators,
- TimeInterval simulation_time_interval)
- : solve_context_(solve_context),
- particle_allocators_(particle_allocators),
- simulation_time_interval_(simulation_time_interval)
- {
- }
-
- SimulationSolveContext &solve_context()
- {
- return solve_context_;
- }
-
- ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name)
- {
- return particle_allocators_.try_get_allocator(particle_simulation_name);
- }
-
- TimeInterval simulation_time_interval() const
- {
- return simulation_time_interval_;
- }
-};
-
-class ParticleForceContext {
- private:
- SimulationSolveContext &solve_context_;
- const ParticleChunkContext &particle_chunk_context_;
- MutableSpan<float3> force_dst_;
-
- public:
- ParticleForceContext(SimulationSolveContext &solve_context,
- const ParticleChunkContext &particle_chunk_context,
- MutableSpan<float3> force_dst)
- : solve_context_(solve_context),
- particle_chunk_context_(particle_chunk_context),
- force_dst_(force_dst)
- {
- }
-
- SimulationSolveContext &solve_context()
- {
- return solve_context_;
- }
-
- const ParticleChunkContext &particle_chunk() const
- {
- return particle_chunk_context_;
- }
-
- MutableSpan<float3> force_dst()
- {
- return force_dst_;
- }
-};
-
void initialize_simulation_states(Simulation &simulation,
Depsgraph &depsgraph,
- const SimulationInfluences &influences);
+ const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map);
void solve_simulation_time_step(Simulation &simulation,
Depsgraph &depsgraph,
const SimulationInfluences &influences,
+ const bke::PersistentDataHandleMap &handle_map,
+ const DependencyAnimations &dependency_animations,
float time_step);
} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver_influences.cc b/source/blender/simulation/intern/simulation_solver_influences.cc
new file mode 100644
index 00000000000..3485d7c7bfb
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver_influences.cc
@@ -0,0 +1,57 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "simulation_solver_influences.hh"
+
+#include "DNA_object_types.h"
+
+namespace blender::sim {
+
+ParticleForce::~ParticleForce()
+{
+}
+
+ParticleEmitter::~ParticleEmitter()
+{
+}
+
+ParticleAction::~ParticleAction()
+{
+}
+
+ParticleEvent::~ParticleEvent()
+{
+}
+
+DependencyAnimations::~DependencyAnimations()
+{
+}
+
+bool DependencyAnimations::is_object_transform_changing(Object &UNUSED(object)) const
+{
+ return false;
+}
+
+void DependencyAnimations::get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const
+{
+ assert_same_size(simulation_times, r_transforms);
+ float4x4 world_matrix = object.obmat;
+ r_transforms.fill(world_matrix);
+}
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_solver_influences.hh b/source/blender/simulation/intern/simulation_solver_influences.hh
new file mode 100644
index 00000000000..d7914819d36
--- /dev/null
+++ b/source/blender/simulation/intern/simulation_solver_influences.hh
@@ -0,0 +1,234 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "BLI_float3.hh"
+#include "BLI_float4x4.hh"
+#include "BLI_multi_value_map.hh"
+#include "BLI_span.hh"
+
+#include "DNA_simulation_types.h"
+
+#include "FN_attributes_ref.hh"
+
+#include "BKE_persistent_data_handle.hh"
+#include "BKE_simulation.h"
+
+#include "particle_allocator.hh"
+#include "time_interval.hh"
+
+namespace blender::sim {
+
+using fn::AttributesInfo;
+using fn::AttributesInfoBuilder;
+using fn::AttributesRef;
+using fn::CPPType;
+using fn::GMutableSpan;
+using fn::GSpan;
+using fn::MutableAttributesRef;
+
+struct ParticleEmitterContext;
+struct ParticleForceContext;
+struct ParticleActionContext;
+struct ParticleEventFilterContext;
+
+class ParticleEmitter {
+ public:
+ virtual ~ParticleEmitter();
+ virtual void emit(ParticleEmitterContext &context) const = 0;
+};
+
+class ParticleForce {
+ public:
+ virtual ~ParticleForce();
+ virtual void add_force(ParticleForceContext &context) const = 0;
+};
+
+class ParticleAction {
+ public:
+ virtual ~ParticleAction();
+ virtual void execute(ParticleActionContext &context) const = 0;
+};
+
+class ParticleEvent {
+ public:
+ virtual ~ParticleEvent();
+ virtual void filter(ParticleEventFilterContext &context) const = 0;
+ virtual void execute(ParticleActionContext &context) const = 0;
+};
+
+struct SimulationInfluences {
+ MultiValueMap<std::string, const ParticleForce *> particle_forces;
+ MultiValueMap<std::string, const ParticleAction *> particle_birth_actions;
+ MultiValueMap<std::string, const ParticleAction *> particle_time_step_begin_actions;
+ MultiValueMap<std::string, const ParticleAction *> particle_time_step_end_actions;
+ MultiValueMap<std::string, const ParticleEvent *> particle_events;
+ Map<std::string, AttributesInfoBuilder *> particle_attributes_builder;
+ Vector<const ParticleEmitter *> particle_emitters;
+};
+
+class SimulationStateMap {
+ private:
+ Map<StringRefNull, SimulationState *> states_by_name_;
+ MultiValueMap<StringRefNull, SimulationState *> states_by_type_;
+
+ public:
+ void add(SimulationState *state)
+ {
+ states_by_name_.add_new(state->name, state);
+ states_by_type_.add(state->type, state);
+ }
+
+ template<typename StateType> StateType *lookup(StringRef name) const
+ {
+ const char *type = BKE_simulation_get_state_type_name<StateType>();
+ return (StateType *)this->lookup_name_type(name, type);
+ }
+
+ template<typename StateType> Span<StateType *> lookup() const
+ {
+ const char *type = BKE_simulation_get_state_type_name<StateType>();
+ return this->lookup_type(type).cast<StateType *>();
+ }
+
+ SimulationState *lookup_name_type(StringRef name, StringRef type) const
+ {
+ SimulationState *state = states_by_name_.lookup_default_as(name, nullptr);
+ if (state == nullptr) {
+ return nullptr;
+ }
+ if (state->type == type) {
+ return state;
+ }
+ return nullptr;
+ }
+
+ Span<SimulationState *> lookup_type(StringRef type) const
+ {
+ return states_by_type_.lookup_as(type);
+ }
+};
+
+class DependencyAnimations {
+ public:
+ ~DependencyAnimations();
+
+ virtual bool is_object_transform_changing(Object &object) const;
+ virtual void get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const;
+};
+
+struct SimulationSolveContext {
+ Simulation &simulation;
+ Depsgraph &depsgraph;
+ const SimulationInfluences &influences;
+ TimeInterval solve_interval;
+ const SimulationStateMap &state_map;
+ const bke::PersistentDataHandleMap &handle_map;
+ const DependencyAnimations &dependency_animations;
+};
+
+class ParticleAllocators {
+ private:
+ Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators_;
+
+ public:
+ ParticleAllocators(Map<std::string, std::unique_ptr<ParticleAllocator>> &allocators)
+ : allocators_(allocators)
+ {
+ }
+
+ ParticleAllocator *try_get_allocator(StringRef particle_simulation_name)
+ {
+ auto *ptr = allocators_.lookup_ptr_as(particle_simulation_name);
+ if (ptr != nullptr) {
+ return ptr->get();
+ }
+ else {
+ return nullptr;
+ }
+ }
+};
+
+struct ParticleChunkIntegrationContext {
+ MutableSpan<float3> position_diffs;
+ MutableSpan<float3> velocity_diffs;
+ MutableSpan<float> durations;
+ float end_time;
+};
+
+struct ParticleChunkContext {
+ ParticleSimulationState &state;
+ IndexMask index_mask;
+ MutableAttributesRef attributes;
+ ParticleChunkIntegrationContext *integration = nullptr;
+
+ void update_diffs_after_velocity_change()
+ {
+ if (integration == nullptr) {
+ return;
+ }
+
+ Span<float> remaining_durations = integration->durations;
+ MutableSpan<float3> position_diffs = integration->position_diffs;
+ Span<float3> velocities = attributes.get<float3>("Velocity");
+
+ for (int i : index_mask) {
+ const float duration = remaining_durations[i];
+ /* This is certainly not a perfect way to "re-integrate" the velocity, but it should be good
+ * enough for most use cases. Changing the velocity in an instant is not physically correct
+ * anyway. */
+ position_diffs[i] = velocities[i] * duration;
+ }
+ }
+};
+
+struct ParticleEmitterContext {
+ SimulationSolveContext &solve_context;
+ ParticleAllocators &particle_allocators;
+ TimeInterval emit_interval;
+
+ template<typename StateType> StateType *lookup_state(StringRef name)
+ {
+ return solve_context.state_map.lookup<StateType>(name);
+ }
+
+ ParticleAllocator *try_get_particle_allocator(StringRef particle_simulation_name)
+ {
+ return particle_allocators.try_get_allocator(particle_simulation_name);
+ }
+};
+
+struct ParticleForceContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+ MutableSpan<float3> force_dst;
+};
+
+struct ParticleActionContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+};
+
+struct ParticleEventFilterContext {
+ SimulationSolveContext &solve_context;
+ ParticleChunkContext &particles;
+ MutableSpan<float> factor_dst;
+};
+
+} // namespace blender::sim
diff --git a/source/blender/simulation/intern/simulation_update.cc b/source/blender/simulation/intern/simulation_update.cc
index 09219e0238f..32b582977d0 100644
--- a/source/blender/simulation/intern/simulation_update.cc
+++ b/source/blender/simulation/intern/simulation_update.cc
@@ -17,8 +17,11 @@
#include "SIM_simulation_update.hh"
#include "BKE_customdata.h"
+#include "BKE_lib_id.h"
+#include "BKE_object.h"
#include "BKE_simulation.h"
+#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "DNA_simulation_types.h"
@@ -29,8 +32,11 @@
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_rand.h"
+#include "BLI_set.hh"
#include "BLI_vector.hh"
+#include "NOD_node_tree_dependencies.hh"
+
#include "particle_function.hh"
#include "simulation_collect_influences.hh"
#include "simulation_solver.hh"
@@ -88,6 +94,131 @@ static void update_simulation_state_list(Simulation *simulation,
add_missing_states(simulation, required_states);
}
+class SampledDependencyAnimations : public DependencyAnimations {
+ private:
+ TimeInterval simulation_time_interval_;
+ MultiValueMap<Object *, float4x4> object_transforms_cache_;
+
+ public:
+ SampledDependencyAnimations(TimeInterval simulation_time_interval)
+ : simulation_time_interval_(simulation_time_interval)
+ {
+ }
+
+ void add_object_transforms(Object &object, Span<float4x4> transforms)
+ {
+ object_transforms_cache_.add_multiple(&object, transforms);
+ }
+
+ bool is_object_transform_changing(Object &object) const
+ {
+ return object_transforms_cache_.lookup(&object).size() >= 2;
+ }
+
+ void get_object_transforms(Object &object,
+ Span<float> simulation_times,
+ MutableSpan<float4x4> r_transforms) const
+ {
+ assert_same_size(simulation_times, r_transforms);
+ Span<float4x4> cached_transforms = object_transforms_cache_.lookup(&object);
+ if (cached_transforms.size() == 0) {
+ r_transforms.fill(object.obmat);
+ return;
+ }
+ if (cached_transforms.size() == 1) {
+ r_transforms.fill(cached_transforms[0]);
+ return;
+ }
+
+ for (int i : simulation_times.index_range()) {
+ const float simulation_time = simulation_times[i];
+ if (simulation_time <= simulation_time_interval_.start()) {
+ r_transforms[i] = cached_transforms.first();
+ continue;
+ }
+ if (simulation_time >= simulation_time_interval_.stop()) {
+ r_transforms[i] = cached_transforms.last();
+ continue;
+ }
+ const float factor = simulation_time_interval_.factor_at_time(simulation_time);
+ BLI_assert(factor > 0.0f && factor < 1.0f);
+ const float scaled_factor = factor * (cached_transforms.size() - 1);
+ const int lower_sample = (int)scaled_factor;
+ const int upper_sample = lower_sample + 1;
+ const float mix_factor = scaled_factor - lower_sample;
+ r_transforms[i] = float4x4::interpolate(
+ cached_transforms[lower_sample], cached_transforms[upper_sample], mix_factor);
+ }
+ }
+};
+
+static void sample_object_transforms(Object &object,
+ Depsgraph &depsgraph,
+ Scene &scene,
+ TimeInterval scene_frame_interval,
+ MutableSpan<float4x4> r_transforms)
+{
+ if (r_transforms.size() == 0) {
+ return;
+ }
+ if (r_transforms.size() == 1) {
+ r_transforms[0] = object.obmat;
+ return;
+ }
+
+ Array<float> frames(r_transforms.size());
+ scene_frame_interval.compute_uniform_samples(frames);
+
+ for (int i : frames.index_range()) {
+ float frame = frames[i];
+ const int recursion_depth = 5;
+ BKE_object_modifier_update_subframe(
+ &depsgraph, &scene, &object, false, recursion_depth, frame, eModifierType_None);
+ r_transforms[i] = object.obmat;
+ }
+}
+
+template<typename T> static bool all_values_equal(Span<T> values)
+{
+ if (values.size() == 0) {
+ return true;
+ }
+ for (const T &value : values.drop_front(1)) {
+ if (value != values[0]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static void prepare_dependency_animations(Depsgraph &depsgraph,
+ Scene &scene,
+ Simulation &simulation,
+ TimeInterval scene_frame_interval,
+ SampledDependencyAnimations &r_dependency_animations)
+{
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation.dependencies) {
+ ID *id_cow = DEG_get_evaluated_id(&depsgraph, dependency->id);
+ if (id_cow == nullptr) {
+ continue;
+ }
+ if (GS(id_cow->name) != ID_OB) {
+ continue;
+ }
+ Object &object_cow = *(Object *)id_cow;
+ constexpr int sample_count = 10;
+ Array<float4x4, sample_count> transforms(sample_count);
+ sample_object_transforms(object_cow, depsgraph, scene, scene_frame_interval, transforms);
+
+ /* If all samples are the same, only store one. */
+ Span<float4x4> transforms_to_use = (all_values_equal(transforms.as_span())) ?
+ transforms.as_span().take_front(1) :
+ transforms.as_span();
+
+ r_dependency_animations.add_object_transforms(object_cow, transforms_to_use);
+ }
+}
+
void update_simulation_in_depsgraph(Depsgraph *depsgraph,
Scene *scene_cow,
Simulation *simulation_cow)
@@ -108,13 +239,20 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
SimulationInfluences influences;
RequiredStates required_states;
- /* TODO: Use simulation_cow, but need to add depsgraph relations before that. */
- collect_simulation_influences(*simulation_orig, resources, influences, required_states);
+ collect_simulation_influences(*simulation_cow, resources, influences, required_states);
+
+ bke::PersistentDataHandleMap handle_map;
+ LISTBASE_FOREACH (SimulationDependency *, dependency, &simulation_orig->dependencies) {
+ ID *id_cow = DEG_get_evaluated_id(depsgraph, dependency->id);
+ if (id_cow != nullptr) {
+ handle_map.add(dependency->handle, *id_cow);
+ }
+ }
if (current_frame == 1) {
reinitialize_empty_simulation_states(simulation_orig, required_states);
- initialize_simulation_states(*simulation_orig, *depsgraph, influences);
+ initialize_simulation_states(*simulation_orig, *depsgraph, influences, handle_map);
simulation_orig->current_frame = 1;
copy_states_to_cow(simulation_orig, simulation_cow);
@@ -122,12 +260,97 @@ void update_simulation_in_depsgraph(Depsgraph *depsgraph,
else if (current_frame == simulation_orig->current_frame + 1) {
update_simulation_state_list(simulation_orig, required_states);
- float time_step = 1.0f / 24.0f;
- solve_simulation_time_step(*simulation_orig, *depsgraph, influences, time_step);
+ const float fps = scene_cow->r.frs_sec / scene_cow->r.frs_sec_base;
+ const float time_step = 1.0f / fps;
+ TimeInterval scene_frame_interval(current_frame - 1, 1);
+ TimeInterval simulation_time_interval(simulation_orig->current_simulation_time, time_step);
+ SampledDependencyAnimations dependency_animations{simulation_time_interval};
+ prepare_dependency_animations(
+ *depsgraph, *scene_cow, *simulation_orig, scene_frame_interval, dependency_animations);
+
+ solve_simulation_time_step(
+ *simulation_orig, *depsgraph, influences, handle_map, dependency_animations, time_step);
simulation_orig->current_frame = current_frame;
copy_states_to_cow(simulation_orig, simulation_cow);
}
}
+/* Returns true when dependencies have changed. */
+bool update_simulation_dependencies(Simulation *simulation)
+{
+ nodes::NodeTreeDependencies dependencies = nodes::find_node_tree_dependencies(
+ *simulation->nodetree);
+
+ ListBase *dependency_list = &simulation->dependencies;
+
+ bool dependencies_changed = false;
+
+ Map<ID *, SimulationDependency *> dependency_by_id;
+ Map<SimulationDependency *, int> old_flag_by_dependency;
+ Set<int> used_handles;
+
+ /* Remove unused handle items and clear flags that are reinitialized later. */
+ LISTBASE_FOREACH_MUTABLE (SimulationDependency *, dependency, dependency_list) {
+ if (dependencies.depends_on(dependency->id)) {
+ dependency_by_id.add_new(dependency->id, dependency);
+ used_handles.add_new(dependency->handle);
+ old_flag_by_dependency.add_new(dependency, dependency->flag);
+ dependency->flag &= ~(SIM_DEPENDS_ON_TRANSFORM | SIM_DEPENDS_ON_GEOMETRY);
+ }
+ else {
+ if (dependency->id != nullptr) {
+ id_us_min(dependency->id);
+ }
+ BLI_remlink(dependency_list, dependency);
+ MEM_freeN(dependency);
+ dependencies_changed = true;
+ }
+ }
+
+ /* Add handle items for new id dependencies. */
+ int next_handle = 0;
+ for (ID *id : dependencies.id_dependencies()) {
+ dependency_by_id.lookup_or_add_cb(id, [&]() {
+ while (used_handles.contains(next_handle)) {
+ next_handle++;
+ }
+ used_handles.add_new(next_handle);
+
+ SimulationDependency *dependency = (SimulationDependency *)MEM_callocN(sizeof(*dependency),
+ AT);
+ id_us_plus(id);
+ dependency->id = id;
+ dependency->handle = next_handle;
+ BLI_addtail(dependency_list, dependency);
+
+ return dependency;
+ });
+ }
+
+ /* Set appropriate dependency flags. */
+ for (Object *object : dependencies.transform_dependencies()) {
+ SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
+ dependency->flag |= SIM_DEPENDS_ON_TRANSFORM;
+ }
+ for (Object *object : dependencies.geometry_dependencies()) {
+ SimulationDependency *dependency = dependency_by_id.lookup(&object->id);
+ dependency->flag |= SIM_DEPENDS_ON_GEOMETRY;
+ }
+
+ if (!dependencies_changed) {
+ /* Check if any flags have changed. */
+ LISTBASE_FOREACH (SimulationDependency *, dependency, dependency_list) {
+ uint32_t old_flag = old_flag_by_dependency.lookup_default(dependency, 0);
+ uint32_t new_flag = dependency->flag;
+ if (old_flag != new_flag) {
+ dependencies_changed = true;
+ break;
+ }
+ }
+ }
+
+ return dependencies_changed;
+}
+
} // namespace blender::sim
diff --git a/source/blender/simulation/intern/time_interval.hh b/source/blender/simulation/intern/time_interval.hh
index 6f13634ed06..034628fa9be 100644
--- a/source/blender/simulation/intern/time_interval.hh
+++ b/source/blender/simulation/intern/time_interval.hh
@@ -21,7 +21,7 @@
namespace blender::sim {
/**
- * The start time is inclusive and the end time is exclusive. The duration is zero, the interval
+ * The start time is exclusive and the end time is inclusive. If the duration is zero, the interval
* describes a single point in time.
*/
class TimeInterval {
@@ -40,7 +40,7 @@ class TimeInterval {
return start_;
}
- float end() const
+ float stop() const
{
return start_ + duration_;
}
@@ -49,6 +49,42 @@ class TimeInterval {
{
return duration_;
}
+
+ float time_at_factor(float factor) const
+ {
+ return start_ + factor * duration_;
+ }
+
+ float factor_at_time(float time) const
+ {
+ BLI_assert(duration_ > 0.0f);
+ return (time - start_) / duration_;
+ }
+
+ float safe_factor_at_time(float time) const
+ {
+ if (duration_ > 0.0f) {
+ return this->factor_at_time(time);
+ }
+ return 0.0f;
+ }
+
+ void compute_uniform_samples(MutableSpan<float> r_samples) const
+ {
+ int64_t amount = r_samples.size();
+ if (amount == 0) {
+ return;
+ }
+ if (amount == 1) {
+ r_samples[0] = this->time_at_factor(0.5f);
+ return;
+ }
+
+ const float step = duration_ / (float)(amount - 1);
+ for (int64_t i : r_samples.index_range()) {
+ r_samples[i] = start_ + i * step;
+ }
+ }
};
} // namespace blender::sim
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 332f53c9ee7..07746af4b60 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -98,7 +98,7 @@ void WM_main(struct bContext *C) ATTR_NORETURN;
void WM_init_splash(struct bContext *C);
-void WM_init_opengl(struct Main *bmain);
+void WM_init_opengl(void);
void WM_check(struct bContext *C);
void WM_reinit_gizmomap_all(struct Main *bmain);
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
index e687af15982..87cb4d5f584 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c
@@ -29,7 +29,6 @@
#include "BKE_context.h"
#include "GPU_batch.h"
-#include "GPU_glew.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -453,9 +452,7 @@ bool wm_gizmo_select_and_highlight(bContext *C, wmGizmoMap *gzmap, wmGizmo *gz)
wm_gizmomap_highlight_set(gzmap, C, gz, gz->highlight_part);
return true;
}
- else {
- return false;
- }
+ return false;
}
/**
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
index 67f30f0d7ee..b64d544962d 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
@@ -166,12 +166,10 @@ int WM_gizmo_cmp_temp_fl(const void *gz_a_ptr, const void *gz_b_ptr)
if (gz_a->temp.f < gz_b->temp.f) {
return -1;
}
- else if (gz_a->temp.f > gz_b->temp.f) {
+ if (gz_a->temp.f > gz_b->temp.f) {
return 1;
}
- else {
- return 0;
- }
+ return 0;
}
int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
@@ -181,12 +179,10 @@ int WM_gizmo_cmp_temp_fl_reverse(const void *gz_a_ptr, const void *gz_b_ptr)
if (gz_a->temp.f < gz_b->temp.f) {
return 1;
}
- else if (gz_a->temp.f > gz_b->temp.f) {
+ if (gz_a->temp.f > gz_b->temp.f) {
return -1;
}
- else {
- return 0;
- }
+ return 0;
}
static bool wm_gizmo_keymap_uses_event_modifier(wmWindowManager *wm,
@@ -396,10 +392,9 @@ static int gizmo_select_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE
return OPERATOR_FINISHED;
}
- else {
- BLI_assert(0);
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
+
+ BLI_assert(0);
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
}
void GIZMOGROUP_OT_gizmo_select(wmOperatorType *ot)
@@ -476,9 +471,7 @@ static bool gizmo_tweak_start_and_finish(
}
return true;
}
- else {
- return false;
- }
+ return false;
}
static void gizmo_tweak_finish(bContext *C, wmOperator *op, const bool cancel, bool clear_modal)
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
index 396b59ba6e2..cecd324ff28 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
@@ -38,7 +38,6 @@
#include "ED_select_utils.h"
#include "ED_view3d.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_select.h"
#include "GPU_state.h"
@@ -264,11 +263,10 @@ bool WM_gizmomap_minmax(const wmGizmoMap *gzmap,
}
return i != 0;
}
- else {
- bool ok = false;
- BLI_assert(!"TODO");
- return ok;
- }
+
+ bool ok = false;
+ BLI_assert(!"TODO");
+ return ok;
}
/**
@@ -582,7 +580,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
rcti rect;
/* Almost certainly overkill, but allow for many custom gizmos. */
- GLuint buffer[MAXPICKBUF];
+ uint buffer[MAXPICKBUF];
short hits;
BLI_rcti_init_pt_radius(&rect, co, hotspot);
@@ -625,7 +623,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
GPU_matrix_unproject_with_precalc(&unproj_precalc, co_screen, co_3d_origin);
- GLuint *buf_iter = buffer;
+ uint *buf_iter = buffer;
int hit_found = -1;
float dot_best = FLT_MAX;
@@ -648,10 +646,9 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos,
}
return hit_found;
}
- else {
- const GLuint *hit_near = GPU_select_buffer_near(buffer, hits);
- return hit_near ? hit_near[3] : -1;
- }
+
+ const uint *hit_near = GPU_select_buffer_near(buffer, hits);
+ return hit_near ? hit_near[3] : -1;
}
/**
diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
index 2dc03d1419c..b056ed40943 100644
--- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
+++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_target_props.c
@@ -70,9 +70,7 @@ wmGizmoProperty *WM_gizmo_target_property_find(wmGizmo *gz, const char *idname)
if (index != -1) {
return WM_gizmo_target_property_at_index(gz, index);
}
- else {
- return NULL;
- }
+ return NULL;
}
void WM_gizmo_target_property_def_rna_ptr(wmGizmo *gz,
@@ -195,9 +193,7 @@ float WM_gizmo_target_property_float_get(const wmGizmo *gz, wmGizmoProperty *gz_
if (gz_prop->index == -1) {
return RNA_property_float_get(&gz_prop->ptr, gz_prop->prop);
}
- else {
- return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
- }
+ return RNA_property_float_get_index(&gz_prop->ptr, gz_prop->prop, gz_prop->index);
}
void WM_gizmo_target_property_float_set(bContext *C,
@@ -255,9 +251,7 @@ bool WM_gizmo_target_property_float_range_get(const wmGizmo *gz,
gz_prop->custom_func.range_get_fn(gz, gz_prop, range);
return true;
}
- else {
- return false;
- }
+ return false;
}
float step, precision;
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 2112477e62a..43c08a2b980 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -293,7 +293,7 @@ void WM_keyconfig_init(bContext *C)
/* initialize only after python init is done, for keymaps that
* use python operators */
- if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) == 0) {
+ if (CTX_py_init_get(C) && (wm->initialized & WM_KEYCONFIG_IS_INIT) == 0) {
/* create default key config, only initialize once,
* it's persistent across sessions */
if (!(wm->defaultconf->flag & KEYCONF_INIT_DEFAULT)) {
@@ -308,7 +308,7 @@ void WM_keyconfig_init(bContext *C)
WM_keyconfig_update_tag(NULL, NULL);
WM_keyconfig_update(wm);
- wm->initialized |= WM_KEYCONFIG_IS_INITIALIZED;
+ wm->initialized |= WM_KEYCONFIG_IS_INIT;
}
}
@@ -334,7 +334,7 @@ void WM_check(bContext *C)
if (!G.background) {
/* case: fileread */
- if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
WM_keyconfig_init(C);
WM_autosave_init(wm);
}
@@ -345,9 +345,9 @@ void WM_check(bContext *C)
/* case: fileread */
/* note: this runs in bg mode to set the screen context cb */
- if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
- ED_screens_initialize(bmain, wm);
- wm->initialized |= WM_WINDOW_IS_INITIALIZED;
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
+ ED_screens_init(bmain, wm);
+ wm->initialized |= WM_WINDOW_IS_INIT;
}
}
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 2af68956923..8e89c08a831 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -121,7 +121,7 @@ static GHOST_TStandardCursor convert_to_ghost_standard_cursor(WMCursorType curs)
}
static void window_set_custom_cursor(
- wmWindow *win, const uchar mask[16][2], uchar bitmap[16][2], int hotx, int hoty)
+ wmWindow *win, const uchar mask[16][2], const uchar bitmap[16][2], int hotx, int hoty)
{
GHOST_SetCustomCursorShape(
win->ghostwin, (GHOST_TUns8 *)bitmap, (GHOST_TUns8 *)mask, 16, 16, hotx, hoty, true);
@@ -319,15 +319,15 @@ bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event)
wm_cursor_warp_relative(win, 0, fac);
return 1;
}
- else if (event->type == EVT_DOWNARROWKEY) {
+ if (event->type == EVT_DOWNARROWKEY) {
wm_cursor_warp_relative(win, 0, -fac);
return 1;
}
- else if (event->type == EVT_LEFTARROWKEY) {
+ if (event->type == EVT_LEFTARROWKEY) {
wm_cursor_warp_relative(win, -fac, 0);
return 1;
}
- else if (event->type == EVT_RIGHTARROWKEY) {
+ if (event->type == EVT_RIGHTARROWKEY) {
wm_cursor_warp_relative(win, fac, 0);
return 1;
}
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index ad3fc7a1302..ec18a401fa4 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -39,7 +39,6 @@
#include "BKE_context.h"
#include "BKE_idtype.h"
-#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_state.h"
#include "GPU_viewport.h"
@@ -297,7 +296,7 @@ void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)
}
return;
}
- else if (GS(drag_id->id->name) != GS(id->name)) {
+ if (GS(drag_id->id->name) != GS(id->name)) {
BLI_assert(!"All dragged IDs must have the same type");
return;
}
@@ -356,7 +355,7 @@ static const char *wm_drag_name(wmDrag *drag)
if (single) {
return id->name + 2;
}
- else if (id) {
+ if (id) {
return BKE_idtype_idcode_to_name_plural(GS(id->name));
}
break;
@@ -424,9 +423,8 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
y,
drag->imb->x,
drag->imb->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
drag->imb->rect,
drag->scale,
drag->scale,
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index fdbc7a7d136..b8cb5432a49 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -52,7 +52,6 @@
#include "ED_view3d.h"
#include "GPU_context.h"
-#include "GPU_draw.h"
#include "GPU_framebuffer.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@@ -208,7 +207,7 @@ static bool wm_draw_region_stereo_set(Main *bmain,
if (region->regiontype == RGN_TYPE_PREVIEW) {
return true;
}
- else if (region->regiontype == RGN_TYPE_WINDOW) {
+ if (region->regiontype == RGN_TYPE_WINDOW) {
return (sseq->draw_flag & SEQ_DRAW_BACKDROP) != 0;
}
}
@@ -521,9 +520,7 @@ GPUTexture *wm_draw_region_texture(ARegion *region, int view)
if (viewport) {
return GPU_viewport_color_texture(viewport, view);
}
- else {
- return GPU_offscreen_color_texture(region->draw_buffer->offscreen);
- }
+ return GPU_offscreen_color_texture(region->draw_buffer->offscreen);
}
void wm_draw_region_blend(ARegion *region, int view, bool blend)
@@ -573,8 +570,8 @@ void wm_draw_region_blend(ARegion *region, int view, bool blend)
}
/* Not the same layout as rectf/recti. */
- float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax};
- float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax};
+ const float rectt[4] = {rect_tex.xmin, rect_tex.ymin, rect_tex.xmax, rect_tex.ymax};
+ const float rectg[4] = {rect_geo.xmin, rect_geo.ymin, rect_geo.xmax, rect_geo.ymax};
if (blend) {
/* GL_ONE because regions drawn offscreen have premultiplied alpha. */
@@ -1001,7 +998,7 @@ void wm_draw_update(bContext *C)
wmWindow *win;
GPU_context_main_lock();
- GPU_free_unused_buffers();
+ BKE_image_free_unused_gpu_textures();
for (win = wm->windows.first; win; win = win->next) {
#ifdef WIN32
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 05ef4bfac30..0941dd49d23 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -597,7 +597,7 @@ static int wm_handler_ui_call(bContext *C,
if (is_wheel) {
return WM_HANDLER_CONTINUE;
}
- else if (wm_event_always_pass(event) == 0) {
+ if (wm_event_always_pass(event) == 0) {
do_wheel_ui = true;
}
}
@@ -783,7 +783,7 @@ bool WM_operator_poll(bContext *C, wmOperatorType *ot)
if (ot->pyop_poll) {
return ot->pyop_poll(C, ot);
}
- else if (ot->poll) {
+ if (ot->poll) {
return ot->poll(C);
}
@@ -1095,7 +1095,7 @@ bool WM_operator_repeat_check(const bContext *UNUSED(C), wmOperator *op)
if (op->type->exec != NULL) {
return true;
}
- else if (op->opm) {
+ if (op->opm) {
/* for macros, check all have exec() we can call */
wmOperatorTypeMacro *otmacro;
for (otmacro = op->opm->type->macro.first; otmacro; otmacro = otmacro->next) {
@@ -1816,10 +1816,10 @@ static bool wm_eventmatch(const wmEvent *winevent, const wmKeyMapItem *kmi)
/* tablet events can occur on hover + keypress */
return false;
}
- else if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) {
+ if ((kmitype == TABLET_STYLUS) && (wmtab->active != EVT_TABLET_STYLUS)) {
return false;
}
- else if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) {
+ if ((kmitype == TABLET_ERASER) && (wmtab->active != EVT_TABLET_ERASER)) {
return false;
}
}
@@ -2434,13 +2434,11 @@ static int wm_handlers_do_keymap_with_keymap_handler(
}
break;
}
+ if (action & WM_HANDLER_HANDLED) {
+ CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
+ }
else {
- if (action & WM_HANDLER_HANDLED) {
- CLOG_INFO(WM_LOG_HANDLERS, 2, "handled - and pass on! '%s'", kmi->idname);
- }
- else {
- CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
- }
+ CLOG_INFO(WM_LOG_HANDLERS, 2, "un-handled '%s'", kmi->idname);
}
}
}
@@ -2492,16 +2490,14 @@ static int wm_handlers_do_keymap_with_gizmo_handler(
}
break;
}
- else {
- if (action & WM_HANDLER_HANDLED) {
- if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
- printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
- }
- }
- else {
- PRINT("%s: un-handled '%s'\n", __func__, kmi->idname);
+ if (action & WM_HANDLER_HANDLED) {
+ if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) {
+ printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname);
}
}
+ else {
+ PRINT("%s: un-handled '%s'\n", __func__, kmi->idname);
+ }
}
}
}
@@ -3126,13 +3122,9 @@ static bool wm_event_pie_filter(wmWindow *win, const wmEvent *event)
win->lock_pie_event = EVENT_NONE;
return false;
}
- else {
- return true;
- }
- }
- else {
- return false;
+ return true;
}
+ return false;
}
/**
@@ -3692,10 +3684,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm,
handler->keymap_tool = area->runtime.tool;
return km;
}
- else {
- printf(
- "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
- }
+ printf(
+ "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
}
}
return NULL;
@@ -3716,10 +3706,8 @@ wmKeyMap *WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, wmEventHandle
handler->keymap_tool = area->runtime.tool;
return km;
}
- else {
- printf(
- "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
- }
+ printf(
+ "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname);
}
}
return NULL;
@@ -3775,12 +3763,10 @@ static bool event_or_prev_in_rect(const wmEvent *event, const rcti *rect)
if (BLI_rcti_isect_pt(rect, event->x, event->y)) {
return true;
}
- else if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) {
+ if (event->type == MOUSEMOVE && BLI_rcti_isect_pt(rect, event->prevx, event->prevy)) {
return true;
}
- else {
- return false;
- }
+ return false;
}
static bool handler_region_v2d_mask_test(const ARegion *region, const wmEvent *event)
@@ -3966,138 +3952,137 @@ static int convert_key(GHOST_TKey key)
if (key >= GHOST_kKeyA && key <= GHOST_kKeyZ) {
return (EVT_AKEY + ((int)key - GHOST_kKeyA));
}
- else if (key >= GHOST_kKey0 && key <= GHOST_kKey9) {
+ if (key >= GHOST_kKey0 && key <= GHOST_kKey9) {
return (EVT_ZEROKEY + ((int)key - GHOST_kKey0));
}
- else if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) {
+ if (key >= GHOST_kKeyNumpad0 && key <= GHOST_kKeyNumpad9) {
return (EVT_PAD0 + ((int)key - GHOST_kKeyNumpad0));
}
- else if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) {
+ if (key >= GHOST_kKeyF1 && key <= GHOST_kKeyF24) {
return (EVT_F1KEY + ((int)key - GHOST_kKeyF1));
}
- else {
- switch (key) {
- case GHOST_kKeyBackSpace:
- return EVT_BACKSPACEKEY;
- case GHOST_kKeyTab:
- return EVT_TABKEY;
- case GHOST_kKeyLinefeed:
- return EVT_LINEFEEDKEY;
- case GHOST_kKeyClear:
- return 0;
- case GHOST_kKeyEnter:
- return EVT_RETKEY;
-
- case GHOST_kKeyEsc:
- return EVT_ESCKEY;
- case GHOST_kKeySpace:
- return EVT_SPACEKEY;
- case GHOST_kKeyQuote:
- return EVT_QUOTEKEY;
- case GHOST_kKeyComma:
- return EVT_COMMAKEY;
- case GHOST_kKeyMinus:
- return EVT_MINUSKEY;
- case GHOST_kKeyPlus:
- return EVT_PLUSKEY;
- case GHOST_kKeyPeriod:
- return EVT_PERIODKEY;
- case GHOST_kKeySlash:
- return EVT_SLASHKEY;
-
- case GHOST_kKeySemicolon:
- return EVT_SEMICOLONKEY;
- case GHOST_kKeyEqual:
- return EVT_EQUALKEY;
-
- case GHOST_kKeyLeftBracket:
- return EVT_LEFTBRACKETKEY;
- case GHOST_kKeyRightBracket:
- return EVT_RIGHTBRACKETKEY;
- case GHOST_kKeyBackslash:
- return EVT_BACKSLASHKEY;
- case GHOST_kKeyAccentGrave:
- return EVT_ACCENTGRAVEKEY;
-
- case GHOST_kKeyLeftShift:
- return EVT_LEFTSHIFTKEY;
- case GHOST_kKeyRightShift:
- return EVT_RIGHTSHIFTKEY;
- case GHOST_kKeyLeftControl:
- return EVT_LEFTCTRLKEY;
- case GHOST_kKeyRightControl:
- return EVT_RIGHTCTRLKEY;
- case GHOST_kKeyOS:
- return EVT_OSKEY;
- case GHOST_kKeyLeftAlt:
- return EVT_LEFTALTKEY;
- case GHOST_kKeyRightAlt:
- return EVT_RIGHTALTKEY;
- case GHOST_kKeyApp:
- return EVT_APPKEY;
-
- case GHOST_kKeyCapsLock:
- return EVT_CAPSLOCKKEY;
- case GHOST_kKeyNumLock:
- return 0;
- case GHOST_kKeyScrollLock:
- return 0;
-
- case GHOST_kKeyLeftArrow:
- return EVT_LEFTARROWKEY;
- case GHOST_kKeyRightArrow:
- return EVT_RIGHTARROWKEY;
- case GHOST_kKeyUpArrow:
- return EVT_UPARROWKEY;
- case GHOST_kKeyDownArrow:
- return EVT_DOWNARROWKEY;
-
- case GHOST_kKeyPrintScreen:
- return 0;
- case GHOST_kKeyPause:
- return EVT_PAUSEKEY;
-
- case GHOST_kKeyInsert:
- return EVT_INSERTKEY;
- case GHOST_kKeyDelete:
- return EVT_DELKEY;
- case GHOST_kKeyHome:
- return EVT_HOMEKEY;
- case GHOST_kKeyEnd:
- return EVT_ENDKEY;
- case GHOST_kKeyUpPage:
- return EVT_PAGEUPKEY;
- case GHOST_kKeyDownPage:
- return EVT_PAGEDOWNKEY;
-
- case GHOST_kKeyNumpadPeriod:
- return EVT_PADPERIOD;
- case GHOST_kKeyNumpadEnter:
- return EVT_PADENTER;
- case GHOST_kKeyNumpadPlus:
- return EVT_PADPLUSKEY;
- case GHOST_kKeyNumpadMinus:
- return EVT_PADMINUS;
- case GHOST_kKeyNumpadAsterisk:
- return EVT_PADASTERKEY;
- case GHOST_kKeyNumpadSlash:
- return EVT_PADSLASHKEY;
-
- case GHOST_kKeyGrLess:
- return EVT_GRLESSKEY;
-
- case GHOST_kKeyMediaPlay:
- return EVT_MEDIAPLAY;
- case GHOST_kKeyMediaStop:
- return EVT_MEDIASTOP;
- case GHOST_kKeyMediaFirst:
- return EVT_MEDIAFIRST;
- case GHOST_kKeyMediaLast:
- return EVT_MEDIALAST;
-
- default:
- return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */
- }
+
+ switch (key) {
+ case GHOST_kKeyBackSpace:
+ return EVT_BACKSPACEKEY;
+ case GHOST_kKeyTab:
+ return EVT_TABKEY;
+ case GHOST_kKeyLinefeed:
+ return EVT_LINEFEEDKEY;
+ case GHOST_kKeyClear:
+ return 0;
+ case GHOST_kKeyEnter:
+ return EVT_RETKEY;
+
+ case GHOST_kKeyEsc:
+ return EVT_ESCKEY;
+ case GHOST_kKeySpace:
+ return EVT_SPACEKEY;
+ case GHOST_kKeyQuote:
+ return EVT_QUOTEKEY;
+ case GHOST_kKeyComma:
+ return EVT_COMMAKEY;
+ case GHOST_kKeyMinus:
+ return EVT_MINUSKEY;
+ case GHOST_kKeyPlus:
+ return EVT_PLUSKEY;
+ case GHOST_kKeyPeriod:
+ return EVT_PERIODKEY;
+ case GHOST_kKeySlash:
+ return EVT_SLASHKEY;
+
+ case GHOST_kKeySemicolon:
+ return EVT_SEMICOLONKEY;
+ case GHOST_kKeyEqual:
+ return EVT_EQUALKEY;
+
+ case GHOST_kKeyLeftBracket:
+ return EVT_LEFTBRACKETKEY;
+ case GHOST_kKeyRightBracket:
+ return EVT_RIGHTBRACKETKEY;
+ case GHOST_kKeyBackslash:
+ return EVT_BACKSLASHKEY;
+ case GHOST_kKeyAccentGrave:
+ return EVT_ACCENTGRAVEKEY;
+
+ case GHOST_kKeyLeftShift:
+ return EVT_LEFTSHIFTKEY;
+ case GHOST_kKeyRightShift:
+ return EVT_RIGHTSHIFTKEY;
+ case GHOST_kKeyLeftControl:
+ return EVT_LEFTCTRLKEY;
+ case GHOST_kKeyRightControl:
+ return EVT_RIGHTCTRLKEY;
+ case GHOST_kKeyOS:
+ return EVT_OSKEY;
+ case GHOST_kKeyLeftAlt:
+ return EVT_LEFTALTKEY;
+ case GHOST_kKeyRightAlt:
+ return EVT_RIGHTALTKEY;
+ case GHOST_kKeyApp:
+ return EVT_APPKEY;
+
+ case GHOST_kKeyCapsLock:
+ return EVT_CAPSLOCKKEY;
+ case GHOST_kKeyNumLock:
+ return 0;
+ case GHOST_kKeyScrollLock:
+ return 0;
+
+ case GHOST_kKeyLeftArrow:
+ return EVT_LEFTARROWKEY;
+ case GHOST_kKeyRightArrow:
+ return EVT_RIGHTARROWKEY;
+ case GHOST_kKeyUpArrow:
+ return EVT_UPARROWKEY;
+ case GHOST_kKeyDownArrow:
+ return EVT_DOWNARROWKEY;
+
+ case GHOST_kKeyPrintScreen:
+ return 0;
+ case GHOST_kKeyPause:
+ return EVT_PAUSEKEY;
+
+ case GHOST_kKeyInsert:
+ return EVT_INSERTKEY;
+ case GHOST_kKeyDelete:
+ return EVT_DELKEY;
+ case GHOST_kKeyHome:
+ return EVT_HOMEKEY;
+ case GHOST_kKeyEnd:
+ return EVT_ENDKEY;
+ case GHOST_kKeyUpPage:
+ return EVT_PAGEUPKEY;
+ case GHOST_kKeyDownPage:
+ return EVT_PAGEDOWNKEY;
+
+ case GHOST_kKeyNumpadPeriod:
+ return EVT_PADPERIOD;
+ case GHOST_kKeyNumpadEnter:
+ return EVT_PADENTER;
+ case GHOST_kKeyNumpadPlus:
+ return EVT_PADPLUSKEY;
+ case GHOST_kKeyNumpadMinus:
+ return EVT_PADMINUS;
+ case GHOST_kKeyNumpadAsterisk:
+ return EVT_PADASTERKEY;
+ case GHOST_kKeyNumpadSlash:
+ return EVT_PADSLASHKEY;
+
+ case GHOST_kKeyGrLess:
+ return EVT_GRLESSKEY;
+
+ case GHOST_kKeyMediaPlay:
+ return EVT_MEDIAPLAY;
+ case GHOST_kKeyMediaStop:
+ return EVT_MEDIASTOP;
+ case GHOST_kKeyMediaFirst:
+ return EVT_MEDIAFIRST;
+ case GHOST_kKeyMediaLast:
+ return EVT_MEDIALAST;
+
+ default:
+ return EVT_UNKNOWNKEY; /* GHOST_kKeyUnknown */
}
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index f431a6f431b..ef4f2b4a62a 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -258,7 +258,7 @@ static void wm_window_match_keep_current_wm(const bContext *C,
bScreen *screen = NULL;
/* match oldwm to new dbase, only old files */
- wm->initialized &= ~WM_WINDOW_IS_INITIALIZED;
+ wm->initialized &= ~WM_WINDOW_IS_INIT;
/* when loading without UI, no matching needed */
if (load_ui && (screen = CTX_wm_screen(C))) {
@@ -1404,10 +1404,8 @@ bool write_crash_blend(void)
printf("written: %s\n", path);
return 1;
}
- else {
- printf("failed: %s\n", path);
- return 0;
- }
+ printf("failed: %s\n", path);
+ return 0;
}
/**
@@ -2091,9 +2089,7 @@ static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *U
wm_close_file_dialog(C, callback);
return OPERATOR_INTERFACE;
}
- else {
- return wm_homefile_read_exec(C, op);
- }
+ return wm_homefile_read_exec(C, op);
}
static void read_homefile_props(wmOperatorType *ot)
@@ -2255,9 +2251,7 @@ static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op)
wm_close_file_dialog(C, callback);
return OPERATOR_INTERFACE;
}
- else {
- return wm_open_mainfile_dispatch(C, op);
- }
+ return wm_open_mainfile_dispatch(C, op);
}
static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op)
@@ -2328,9 +2322,7 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op)
ED_view3d_local_collections_reset(C, (G.fileflags & G_FILE_NO_UI) != 0);
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static OperatorDispatchTarget wm_open_mainfile_dispatch_targets[] = {
@@ -2475,9 +2467,7 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op)
if (success) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static bool wm_revert_mainfile_poll(bContext *UNUSED(C))
@@ -2572,9 +2562,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
if (success) {
return OPERATOR_FINISHED;
}
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_CANCELLED;
}
static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 31d36603505..6ccc5d79962 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -357,11 +357,11 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path);
return OPERATOR_CANCELLED;
}
- else if (!group) {
+ if (!group) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path);
return OPERATOR_CANCELLED;
}
- else if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) {
+ if (BLI_path_cmp(BKE_main_blendfile_path(bmain), libname) == 0) {
BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path);
return OPERATOR_CANCELLED;
}
@@ -755,7 +755,7 @@ static void lib_relocate_do_remap(Main *bmain,
if (c == '.') {
break;
}
- else if (c < '0' || c > '9') {
+ if (c < '0' || c > '9') {
has_num = false;
break;
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index eee93fc9459..55233168ab2 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -324,7 +324,7 @@ static void draw_filled_lasso(wmGesture *gt)
int(*mcoords)[2] = MEM_mallocN(sizeof(*mcoords) * (mcoords_len + 1), __func__);
int i;
rcti rect;
- float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
+ const float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
for (i = 0; i < mcoords_len; i++, lasso += 2) {
mcoords[i][0] = lasso[0];
@@ -362,18 +362,8 @@ static void draw_filled_lasso(wmGesture *gt)
GPU_shader_uniform_vector(
state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red);
- immDrawPixelsTex(&state,
- rect.xmin,
- rect.ymin,
- w,
- h,
- GL_RED,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
- pixel_buf,
- 1.0f,
- 1.0f,
- NULL);
+ immDrawPixelsTex(
+ &state, rect.xmin, rect.ymin, w, h, GL_R8, false, pixel_buf, 1.0f, 1.0f, NULL);
GPU_shader_unbind();
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 945d5fd42e4..85694dec9c8 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -59,6 +59,7 @@
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_icons.h"
+#include "BKE_image.h"
#include "BKE_keyconfig.h"
#include "BKE_lib_remap.h"
#include "BKE_main.h"
@@ -120,7 +121,6 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "GPU_draw.h"
#include "GPU_init_exit.h"
#include "GPU_material.h"
@@ -171,7 +171,7 @@ void WM_init_state_start_with_console_set(bool value)
*/
static bool opengl_is_init = false;
-void WM_init_opengl(Main *bmain)
+void WM_init_opengl(void)
{
/* must be called only once */
BLI_assert(opengl_is_init == false);
@@ -185,9 +185,6 @@ void WM_init_opengl(Main *bmain)
DRW_opengl_context_create();
GPU_init();
- GPU_set_mipmap(bmain, true);
- GPU_set_linear_mipmap(true);
- GPU_set_anisotropic(U.anisotropic_filter);
GPU_pass_cache_init();
@@ -315,7 +312,7 @@ void WM_init(bContext *C, int argc, const char **argv)
/* sets 3D mouse deadzone */
WM_ndof_deadzone_set(U.ndof_deadzone);
#endif
- WM_init_opengl(G_MAIN);
+ WM_init_opengl();
if (!WM_platform_support_perform_checks()) {
exit(-1);
@@ -578,7 +575,7 @@ void WM_exit_ex(bContext *C, const bool do_python)
BKE_subdiv_exit();
if (opengl_is_init) {
- GPU_free_unused_buffers();
+ BKE_image_free_unused_gpu_textures();
}
BKE_blender_free(); /* blender.c, does entire library and spacetypes */
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 87a19d832c9..c9b125901e7 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -344,9 +344,7 @@ void *WM_jobs_customdata_get(wmJob *wm_job)
if (!wm_job->customdata) {
return wm_job->run_customdata;
}
- else {
- return wm_job->customdata;
- }
+ return wm_job->customdata;
}
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *))
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index d7102a1e8af..d7ff2689a86 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -321,9 +321,7 @@ bool WM_keyconfig_remove(wmWindowManager *wm, wmKeyConfig *keyconf)
return true;
}
- else {
- return false;
- }
+ return false;
}
void WM_keyconfig_clear(wmKeyConfig *keyconf)
@@ -363,7 +361,7 @@ void WM_keyconfig_set_active(wmWindowManager *wm, const char *idname)
WM_keyconfig_update(wm);
BLI_strncpy(U.keyconfigstr, idname, sizeof(U.keyconfigstr));
- if (wm->initialized & WM_KEYCONFIG_IS_INITIALIZED) {
+ if (wm->initialized & WM_KEYCONFIG_IS_INIT) {
U.runtime.is_dirty = true;
}
@@ -448,9 +446,7 @@ bool WM_keymap_remove(wmKeyConfig *keyconf, wmKeyMap *keymap)
return true;
}
- else {
- return false;
- }
+ return false;
}
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
@@ -551,9 +547,7 @@ bool WM_keymap_remove_item(wmKeyMap *keymap, wmKeyMapItem *kmi)
WM_keyconfig_update_tag(keymap, NULL);
return true;
}
- else {
- return false;
- }
+ return false;
}
/** \} */
@@ -1122,7 +1116,7 @@ const char *WM_key_event_string(const short type, const bool compact)
if (platform == MACOS) {
return key_event_glyph_or_text(font_id, IFACE_("Cmd"), "\xe2\x8c\x98");
}
- else if (platform == MSWIN) {
+ if (platform == MSWIN) {
return key_event_glyph_or_text(font_id, IFACE_("Win"), "\xe2\x9d\x96");
}
return IFACE_("OS");
diff --git a/source/blender/windowmanager/intern/wm_keymap_utils.c b/source/blender/windowmanager/intern/wm_keymap_utils.c
index 5ab36b15666..83558bc9192 100644
--- a/source/blender/windowmanager/intern/wm_keymap_utils.c
+++ b/source/blender/windowmanager/intern/wm_keymap_utils.c
@@ -379,7 +379,25 @@ wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
}
/* Animation Generic - after channels */
else if (STRPREFIX(opname, "ANIM_OT")) {
- km = WM_keymap_find_all(wm, "Animation", 0, 0);
+ if (sl->spacetype == SPACE_VIEW3D) {
+ switch (CTX_data_mode_enum(C)) {
+ case CTX_MODE_OBJECT:
+ km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
+ break;
+ case CTX_MODE_POSE:
+ km = WM_keymap_find_all(wm, "Pose", 0, 0);
+ break;
+ default:
+ break;
+ }
+ if (km && !WM_keymap_poll((bContext *)C, km)) {
+ km = NULL;
+ }
+ }
+
+ if (!km) {
+ km = WM_keymap_find_all(wm, "Animation", 0, 0);
+ }
}
/* Graph Editor */
else if (STRPREFIX(opname, "GRAPH_OT")) {
diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c
index 650d5bbe015..457cd0f16be 100644
--- a/source/blender/windowmanager/intern/wm_operator_type.c
+++ b/source/blender/windowmanager/intern/wm_operator_type.c
@@ -606,9 +606,7 @@ char *WM_operatortype_description(struct bContext *C,
if (description[0]) {
return description;
}
- else {
- MEM_freeN(description);
- }
+ MEM_freeN(description);
}
}
@@ -621,9 +619,7 @@ char *WM_operatortype_description(struct bContext *C,
if (info && info[0]) {
return BLI_strdup(info);
}
- else {
- return NULL;
- }
+ return NULL;
}
/** \} */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index d1f65b6271b..8dea1a1031a 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -864,19 +864,17 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
return ret_value | OPERATOR_PASS_THROUGH;
}
- else {
- /* If we are in init phase, and cannot validate init of modal operations,
- * just fall back to basic exec.
- */
- RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
+ /* If we are in init phase, and cannot validate init of modal operations,
+ * just fall back to basic exec.
+ */
+ RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
- ret_value = op->type->exec(C, op);
- OPERATOR_RETVAL_CHECK(ret_value);
+ ret_value = op->type->exec(C, op);
+ OPERATOR_RETVAL_CHECK(ret_value);
- return ret_value | OPERATOR_PASS_THROUGH;
- }
+ return ret_value | OPERATOR_PASS_THROUGH;
}
- else if (event->type == init_event_type && event->val == KM_RELEASE) {
+ if (event->type == init_event_type && event->val == KM_RELEASE) {
RNA_property_boolean_set(op->ptr, wait_to_deselect_prop, false);
ret_value = op->type->exec(C, op);
@@ -884,7 +882,7 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
return ret_value | OPERATOR_PASS_THROUGH;
}
- else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
const int drag_delta[2] = {
mval[0] - event->mval[0],
mval[1] - event->mval[1],
@@ -895,11 +893,9 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (WM_event_drag_test_with_delta(event, drag_delta)) {
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
- else {
- /* Important not to return anything other than PASS_THROUGH here,
- * otherwise it prevents underlying tweak detection code to work properly. */
- return OPERATOR_PASS_THROUGH;
- }
+ /* Important not to return anything other than PASS_THROUGH here,
+ * otherwise it prevents underlying tweak detection code to work properly. */
+ return OPERATOR_PASS_THROUGH;
}
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
@@ -1151,9 +1147,7 @@ int WM_operator_confirm_or_exec(bContext *C, wmOperator *op, const wmEvent *UNUS
if (confirm) {
return WM_operator_confirm_message(C, op, NULL);
}
- else {
- return op->type->exec(C, op);
- }
+ return op->type->exec(C, op);
}
/* op->invoke, opens fileselect if path property not set, otherwise executes */
@@ -1162,10 +1156,8 @@ int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op); /* call exec direct */
}
- else {
- WM_event_add_fileselect(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ WM_event_add_fileselect(C, op);
+ return OPERATOR_RUNNING_MODAL;
}
bool WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format)
@@ -2322,7 +2314,7 @@ static void radial_control_paint_curve(uint pos, Brush *br, float radius, int li
GPU_line_width(2.0f);
immUniformColor4f(0.8f, 0.8f, 0.8f, 0.85f);
float step = (radius * 2.0f) / (float)line_segments;
- BKE_curvemapping_initialize(br->curve);
+ BKE_curvemapping_init(br->curve);
immBegin(GPU_PRIM_LINES, line_segments * 2);
for (int i = 0; i < line_segments; i++) {
float h1 = BKE_brush_curve_strength_clamped(br, fabsf((i * step) - radius), radius);
@@ -2453,7 +2445,7 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void
imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, r2, 80);
if (rmin > 0.0f) {
/* Inner fill circle to increase the contrast of the value */
- float black[3] = {0.0f};
+ const float black[3] = {0.0f};
immUniformColor3fvAlpha(black, 0.2f);
imm_draw_circle_fill_2d(pos, 0.0, 0.0f, rmin, 80);
@@ -2536,10 +2528,8 @@ static int radial_control_get_path(PointerRNA *ctx_ptr,
if (flags & RC_PROP_ALLOW_MISSING) {
return 1;
}
- else {
- BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name);
- return 0;
- }
+ BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name);
+ return 0;
}
/* check property type */
@@ -2591,13 +2581,12 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
(RC_PROP_ALLOW_MISSING | RC_PROP_REQUIRE_BOOL))) {
return 0;
}
+
+ if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) {
+ data_path = "data_path_secondary";
+ }
else {
- if (use_secondary_prop && RNA_property_boolean_get(&use_secondary_ptr, use_secondary_prop)) {
- data_path = "data_path_secondary";
- }
- else {
- data_path = "data_path_primary";
- }
+ data_path = "data_path_primary";
}
if (!radial_control_get_path(&ctx_ptr, op, data_path, &rc->ptr, &rc->prop, 0, 0)) {
@@ -2664,7 +2653,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
if (!radial_control_get_path(&ctx_ptr, op, "image_id", &rc->image_id_ptr, NULL, 0, 0)) {
return 0;
}
- else if (rc->image_id_ptr.data) {
+ if (rc->image_id_ptr.data) {
/* extra check, pointer must be to an ID */
if (!RNA_struct_is_ID(rc->image_id_ptr.type)) {
BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID");
@@ -2841,171 +2830,169 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
radial_control_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
- else {
- handled = false;
- switch (event->type) {
- case EVT_ESCKEY:
- case RIGHTMOUSE:
- /* canceled; restore original value */
- radial_control_set_value(rc, rc->initial_value);
- ret = OPERATOR_CANCELLED;
- break;
-
- case LEFTMOUSE:
- case EVT_PADENTER:
- case EVT_RETKEY:
- /* done; value already set */
- RNA_property_update(C, &rc->ptr, rc->prop);
- ret = OPERATOR_FINISHED;
- break;
-
- case MOUSEMOVE:
- if (!has_numInput) {
- if (rc->slow_mode) {
- if (rc->subtype == PROP_ANGLE) {
- float position[2] = {event->x, event->y};
-
- /* calculate the initial angle here first */
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
-
- /* precision angle gets calculated from dial and gets added later */
- angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
- }
- else {
- delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
- delta[1] = 0.0f;
- if (rc->zoom_prop) {
- RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
- delta[0] /= zoom[0];
- }
+ handled = false;
+ switch (event->type) {
+ case EVT_ESCKEY:
+ case RIGHTMOUSE:
+ /* canceled; restore original value */
+ radial_control_set_value(rc, rc->initial_value);
+ ret = OPERATOR_CANCELLED;
+ break;
- dist = len_v2(delta);
+ case LEFTMOUSE:
+ case EVT_PADENTER:
+ case EVT_RETKEY:
+ /* done; value already set */
+ RNA_property_update(C, &rc->ptr, rc->prop);
+ ret = OPERATOR_FINISHED;
+ break;
- delta[0] = event->x - rc->slow_mouse[0];
+ case MOUSEMOVE:
+ if (!has_numInput) {
+ if (rc->slow_mode) {
+ if (rc->subtype == PROP_ANGLE) {
+ const float position[2] = {event->x, event->y};
- if (rc->zoom_prop) {
- delta[0] /= zoom[0];
- }
+ /* calculate the initial angle here first */
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = rc->initial_mouse[1] - rc->slow_mouse[1];
- dist = dist + 0.1f * (delta[0]);
- }
+ /* precision angle gets calculated from dial and gets added later */
+ angle_precision = -0.1f * BLI_dial_angle(rc->dial, position);
}
else {
- delta[0] = rc->initial_mouse[0] - event->x;
- delta[1] = rc->initial_mouse[1] - event->y;
+ delta[0] = rc->initial_mouse[0] - rc->slow_mouse[0];
+ delta[1] = 0.0f;
+
if (rc->zoom_prop) {
RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
delta[0] /= zoom[0];
- delta[1] /= zoom[1];
}
- if (rc->subtype == PROP_ANGLE) {
- dist = len_v2(delta);
- }
- else {
- dist = clamp_f(-delta[0], 0.0f, FLT_MAX);
+
+ dist = len_v2(delta);
+
+ delta[0] = event->x - rc->slow_mouse[0];
+
+ if (rc->zoom_prop) {
+ delta[0] /= zoom[0];
}
- }
- /* calculate new value and apply snapping */
- switch (rc->subtype) {
- case PROP_NONE:
- case PROP_DISTANCE:
- case PROP_PIXEL:
- new_value = dist;
- if (snap) {
- new_value = ((int)new_value + 5) / 10 * 10;
- }
- break;
- case PROP_PERCENTAGE:
- new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) /
- WM_RADIAL_CONTROL_DISPLAY_WIDTH) *
- 100.0f;
- if (snap) {
- new_value = ((int)(new_value + 2.5f)) / 5 * 5;
- }
- break;
- case PROP_FACTOR:
- new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) /
- WM_RADIAL_CONTROL_DISPLAY_WIDTH;
- if (snap) {
- new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
- }
- /* Invert new value to increase the factor moving the mouse to the right */
- new_value = 1 - new_value;
- break;
- case PROP_ANGLE:
- new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision;
- new_value = fmod(new_value, 2.0f * (float)M_PI);
- if (new_value < 0.0f) {
- new_value += 2.0f * (float)M_PI;
- }
- if (snap) {
- new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
- }
- break;
- default:
- new_value = dist; /* dummy value, should this ever happen? - campbell */
- break;
+ dist = dist + 0.1f * (delta[0]);
}
-
- /* clamp and update */
- CLAMP(new_value, rc->min_value, rc->max_value);
- radial_control_set_value(rc, new_value);
- rc->current_value = new_value;
- handled = true;
- break;
}
- break;
-
- case EVT_LEFTSHIFTKEY:
- case EVT_RIGHTSHIFTKEY: {
- if (event->val == KM_PRESS) {
- rc->slow_mouse[0] = event->x;
- rc->slow_mouse[1] = event->y;
- rc->slow_mode = true;
+ else {
+ delta[0] = rc->initial_mouse[0] - event->x;
+ delta[1] = rc->initial_mouse[1] - event->y;
+ if (rc->zoom_prop) {
+ RNA_property_float_get_array(&rc->zoom_ptr, rc->zoom_prop, zoom);
+ delta[0] /= zoom[0];
+ delta[1] /= zoom[1];
+ }
if (rc->subtype == PROP_ANGLE) {
- float initial_position[2] = {UNPACK2(rc->initial_mouse)};
- float current_position[2] = {UNPACK2(rc->slow_mouse)};
- rc->dial = BLI_dial_initialize(initial_position, 0.0f);
- /* immediately set the position to get a an initial direction */
- BLI_dial_angle(rc->dial, current_position);
+ dist = len_v2(delta);
}
- handled = true;
- }
- if (event->val == KM_RELEASE) {
- rc->slow_mode = false;
- handled = true;
- if (rc->dial) {
- MEM_freeN(rc->dial);
- rc->dial = NULL;
+ else {
+ dist = clamp_f(-delta[0], 0.0f, FLT_MAX);
}
}
+
+ /* calculate new value and apply snapping */
+ switch (rc->subtype) {
+ case PROP_NONE:
+ case PROP_DISTANCE:
+ case PROP_PIXEL:
+ new_value = dist;
+ if (snap) {
+ new_value = ((int)new_value + 5) / 10 * 10;
+ }
+ break;
+ case PROP_PERCENTAGE:
+ new_value = ((dist - WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE) /
+ WM_RADIAL_CONTROL_DISPLAY_WIDTH) *
+ 100.0f;
+ if (snap) {
+ new_value = ((int)(new_value + 2.5f)) / 5 * 5;
+ }
+ break;
+ case PROP_FACTOR:
+ new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH;
+ if (snap) {
+ new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
+ }
+ /* Invert new value to increase the factor moving the mouse to the right */
+ new_value = 1 - new_value;
+ break;
+ case PROP_ANGLE:
+ new_value = atan2f(delta[1], delta[0]) + (float)M_PI + angle_precision;
+ new_value = fmod(new_value, 2.0f * (float)M_PI);
+ if (new_value < 0.0f) {
+ new_value += 2.0f * (float)M_PI;
+ }
+ if (snap) {
+ new_value = DEG2RADF(((int)RAD2DEGF(new_value) + 5) / 10 * 10);
+ }
+ break;
+ default:
+ new_value = dist; /* dummy value, should this ever happen? - campbell */
+ break;
+ }
+
+ /* clamp and update */
+ CLAMP(new_value, rc->min_value, rc->max_value);
+ radial_control_set_value(rc, new_value);
+ rc->current_value = new_value;
+ handled = true;
break;
}
+ break;
+
+ case EVT_LEFTSHIFTKEY:
+ case EVT_RIGHTSHIFTKEY: {
+ if (event->val == KM_PRESS) {
+ rc->slow_mouse[0] = event->x;
+ rc->slow_mouse[1] = event->y;
+ rc->slow_mode = true;
+ if (rc->subtype == PROP_ANGLE) {
+ const float initial_position[2] = {UNPACK2(rc->initial_mouse)};
+ const float current_position[2] = {UNPACK2(rc->slow_mouse)};
+ rc->dial = BLI_dial_init(initial_position, 0.0f);
+ /* immediately set the position to get a an initial direction */
+ BLI_dial_angle(rc->dial, current_position);
+ }
+ handled = true;
+ }
+ if (event->val == KM_RELEASE) {
+ rc->slow_mode = false;
+ handled = true;
+ if (rc->dial) {
+ MEM_freeN(rc->dial);
+ rc->dial = NULL;
+ }
+ }
+ break;
}
+ }
- /* Modal numinput inactive, try to handle numeric inputs last... */
- if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) {
- applyNumInput(&rc->num_input, &numValue);
+ /* Modal numinput inactive, try to handle numeric inputs last... */
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &rc->num_input, event)) {
+ applyNumInput(&rc->num_input, &numValue);
- if (rc->subtype == PROP_ANGLE) {
- numValue = fmod(numValue, 2.0f * (float)M_PI);
- if (numValue < 0.0f) {
- numValue += 2.0f * (float)M_PI;
- }
+ if (rc->subtype == PROP_ANGLE) {
+ numValue = fmod(numValue, 2.0f * (float)M_PI);
+ if (numValue < 0.0f) {
+ numValue += 2.0f * (float)M_PI;
}
+ }
- CLAMP(numValue, rc->min_value, rc->max_value);
- new_value = numValue;
+ CLAMP(numValue, rc->min_value, rc->max_value);
+ new_value = numValue;
- radial_control_set_value(rc, new_value);
+ radial_control_set_value(rc, new_value);
- rc->current_value = new_value;
- radial_control_update_header(op, C);
- return OPERATOR_RUNNING_MODAL;
- }
+ rc->current_value = new_value;
+ radial_control_update_header(op, C);
+ return OPERATOR_RUNNING_MODAL;
}
ED_region_tag_redraw(CTX_wm_region(C));
@@ -3917,6 +3904,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "CLIP_OT_select_box");
WM_modalkeymap_assign(keymap, "CLIP_OT_graph_select_box");
WM_modalkeymap_assign(keymap, "MASK_OT_select_box");
+ WM_modalkeymap_assign(keymap, "PAINT_OT_mask_box_gesture");
WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border");
WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border");
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 74e1c495a00..d0a70596957 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -335,9 +335,8 @@ static void playanim_toscreen(
offs_y + (ps->draw_flip[1] ? span_y : 0.0f),
ibuf->x,
ibuf->y,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- GL_NEAREST,
+ GPU_RGBA8,
+ false,
ibuf->rect,
((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x),
((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
diff --git a/source/blender/windowmanager/intern/wm_stereo.c b/source/blender/windowmanager/intern/wm_stereo.c
index 245560d3795..9667ed5b631 100644
--- a/source/blender/windowmanager/intern/wm_stereo.c
+++ b/source/blender/windowmanager/intern/wm_stereo.c
@@ -353,12 +353,11 @@ int wm_stereo3d_set_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
- else {
- /* without this, the popup won't be freed freed properly T44688 */
- CTX_wm_window_set(C, win_src);
- win_src->stereo3d_format->display_mode = prev_display_mode;
- return OPERATOR_CANCELLED;
- }
+
+ /* without this, the popup won't be freed freed properly T44688 */
+ CTX_wm_window_set(C, win_src);
+ win_src->stereo3d_format->display_mode = prev_display_mode;
+ return OPERATOR_CANCELLED;
}
int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@@ -368,9 +367,7 @@ int wm_stereo3d_set_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(ev
if (wm_stereo3d_set_properties(C, op)) {
return wm_stereo3d_set_exec(C, op);
}
- else {
- return WM_operator_props_dialog_popup(C, op, 250);
- }
+ return WM_operator_props_dialog_popup(C, op, 250);
}
void wm_stereo3d_set_draw(bContext *UNUSED(C), wmOperator *op)
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 477579ed620..0cb76404258 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -29,7 +29,6 @@
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "GPU_glew.h"
#include "GPU_matrix.h"
#include "GPU_viewport.h"
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index e444c5b2109..e0dcd746aea 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -355,10 +355,8 @@ wmWindow *wm_window_copy_test(bContext *C,
WM_event_add_notifier_ex(wm, CTX_wm_window(C), NC_WINDOW | NA_ADDED, NULL);
return win_dst;
}
- else {
- wm_window_close(C, wm, win_dst);
- return NULL;
- }
+ wm_window_close(C, wm, win_dst);
+ return NULL;
}
/** \} */
@@ -813,9 +811,7 @@ static bool wm_window_update_size_position(wmWindow *win)
win->posy = posy;
return true;
}
- else {
- return false;
- }
+ return false;
}
/**
@@ -840,11 +836,10 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
if (win->ghostwin) {
return win;
}
- else {
- wm_window_close(C, wm, win);
- CTX_wm_window_set(C, win_prev);
- return NULL;
- }
+
+ wm_window_close(C, wm, win);
+ CTX_wm_window_set(C, win_prev);
+ return NULL;
}
/**
@@ -969,13 +964,12 @@ wmWindow *WM_window_open_temp(bContext *C,
GHOST_SetTitle(win->ghostwin, title);
return win;
}
- else {
- /* very unlikely! but opening a new window can fail */
- wm_window_close(C, wm, win);
- CTX_wm_window_set(C, win_prev);
- return NULL;
- }
+ /* very unlikely! but opening a new window can fail */
+ wm_window_close(C, wm, win);
+ CTX_wm_window_set(C, win_prev);
+
+ return NULL;
}
/* ****************** Operators ****************** */
@@ -1206,7 +1200,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
/* Ghost now can call this function for life resizes,
* but it should return if WM didn't initialize yet.
* Can happen on file read (especially full size window). */
- if ((wm->initialized & WM_WINDOW_IS_INITIALIZED) == 0) {
+ if ((wm->initialized & WM_WINDOW_IS_INIT) == 0) {
return 1;
}
if (!ghostwin) {
@@ -1215,15 +1209,13 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
puts("<!> event has no window");
return 1;
}
- else if (!GHOST_ValidWindow(g_system, ghostwin)) {
+ if (!GHOST_ValidWindow(g_system, ghostwin)) {
/* XXX - should be checked, why are we getting an event here, and */
/* what is it? */
puts("<!> event has invalid window");
return 1;
}
- else {
- win = GHOST_GetWindowUserData(ghostwin);
- }
+ win = GHOST_GetWindowUserData(ghostwin);
switch (type) {
case GHOST_kEventWindowDeactivate:
diff --git a/source/blender/windowmanager/wm_draw.h b/source/blender/windowmanager/wm_draw.h
index a26c02317d0..4997361b485 100644
--- a/source/blender/windowmanager/wm_draw.h
+++ b/source/blender/windowmanager/wm_draw.h
@@ -23,8 +23,6 @@
#pragma once
-#include "GPU_glew.h"
-
struct GPUOffScreen;
struct GPUTexture;
struct GPUViewport;
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index c564f74b771..b44f006cde8 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -183,16 +183,15 @@ static wmXrSessionStateEvent wm_xr_session_state_to_event(const wmXrSessionState
if (!state->is_view_data_set) {
return SESSION_STATE_EVENT_START;
}
- else if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) {
+ if (wm_xr_session_draw_data_needs_reset_to_base_pose(state, settings)) {
return SESSION_STATE_EVENT_RESET_TO_BASE_POSE;
}
- else {
- const bool position_tracking_toggled = ((state->prev_settings_flag &
- XR_SESSION_USE_POSITION_TRACKING) !=
- (settings->flag & XR_SESSION_USE_POSITION_TRACKING));
- if (position_tracking_toggled) {
- return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE;
- }
+
+ const bool position_tracking_toggled = ((state->prev_settings_flag &
+ XR_SESSION_USE_POSITION_TRACKING) !=
+ (settings->flag & XR_SESSION_USE_POSITION_TRACKING));
+ if (position_tracking_toggled) {
+ return SESSION_STATE_EVENT_POSITON_TRACKING_TOGGLE;
}
return SESSION_STATE_EVENT_NONE;